Перевірка випадкових самоскидів


33

Майже шість років тому колега PPCG steenslag поставив наступне виклик:

У стандартних кубиках (гинуть) числа розташовані так, що протилежні грані додають до семи. Напишіть найкоротшу можливу програму на бажаній мові, яка виводить випадковий кидок з наступним 9 випадковими накидами. Перекидання - це чверть обороту кісток, наприклад, якщо кістка стоїть перед 5, усі можливі відливи 1,3,4 та 6.

Приклад бажаного виходу:

1532131356

Отже, тепер, коли всі повністю забули про це, і виграшну відповідь вже давно прийнято, ми будемо писати програму для перевірки послідовностей відмирань, породжених поданими рішеннями. (Це має сенс. Просто зробіть вигляд, що це робить.)

Виклик

Вашій програмі або функції надається така послідовність, як 1532131356. Перевірте, що кожна послідовна цифра:

  • Не дорівнює попередній цифрі
  • Не дорівнює 7 мінус попередній розряд

(Не потрібно підтверджувати першу цифру.)

Правила

  • Ваша програма повинна повернути значення "truthy", якщо вхід правильний, а значення фальси в іншому випадку.
  • Можна припустити, що вхід складається лише з цифр 1-6 і має принаймні 1 символ. Послідовності не матимуть фіксованої довжини, як у виклику steenslag.
  • Ви можете приймати дані як рядок ( "324324"), масив або схожу на масив структуру даних ( [1,3,5]) або як декілька аргументів ( yourFunction(1,2,4)).

Застосовуються стандартні правила вводу / виводу та лазівки .

Тестові справи

Truthy

1353531414
3132124215
4142124136
46
4264626313135414154
6
2642156451212623232354621262412315654626212421451351563264123656353126413154124151545145146535351323
5414142

Фальсі

  • Повторна цифра

    11
    3132124225
    6423126354214136312144245354241324231415135454535141512135141323542451231236354513265426114231536245
    553141454631
    14265411
    
  • Протилежна сторона штампу

    16
    42123523545426464236231321
    61362462636351
    62362462636361
    

Відповіді:


14

Python 2, 43 45 байт

lambda s:reduce(lambda p,n:n*(7-p!=n!=p>0),s)

43 байти (надихнув @Zgarb)

lambda s:reduce(lambda p,n:n*(p>0<n^p<7),s)

Ця функція поєднує мою операцію зменшення з логічною біткою з відповіді @ Zgarb, для комбінації, яка коротша, ніж обидві.

Обидва відповіді виводять наступне:

  • 0, якщо введення не є дійсною послідовністю
  • Остання цифра послідовності, якщо вона дійсна

4
Ласкаво просимо до PPCG. Це дуже приємна перша відповідь.
Пшеничний майстер

1
Це не працює приблизно для половини помилкових випадків. Наприклад, 3132124225повертається 5.
Джейк Кобб

Ви можете виправити це за допомогою n and p*(7-p!=n!=p).
Джейк Кобб

@JakeCobb Слід працювати з усіма тестовими справами зараз. На жаль, зараз це на 2 байти довше :(
1616

Яке розумне використання скорочення, передаючи кожне значення на наступний крок.
xnor

9

Пітон, 44 байти

lambda x:all(0<a^b<7for a,b in zip(x,x[1:]))

Побітна магія! Це анонімна функція, яка приймає список цілих чисел і перевіряє, чи значення XOR кожні два послідовних елемента становить від 1 до 6 включно.

Чому це працює

По-перше, XOR завжди знаходиться між 0 і 7 включно, оскільки 7 знаходиться 111в базі 2, а наші номери мають максимум 3 двійкові цифри. За рівність, a^b == 0якщо і тільки якщо a == b. Також ми маємо 7-a == 7^aколи 0 ≤ a ≤ 7і, отже, a^b == 7якщо і тільки якщо a == 7^b == 7-b.


7

05AB1E , 11 9 байт

-2 байти для розумної ідеї Ovable використовувати продукт.

¥¹D7-Á+«P

Спробуйте в Інтернеті!

¥           # Push deltas.
 ¹D7-Á      # Push original array, and 7 - [Array] shifted right once.
      +     # Add original to the 7 - [Array] shifted right.
       «    # Concat both.
        P   # Product, if either contain a zero, results in 0, meaning false.

Третій підхід із використанням 05AB1E, який не використовує парної команди:

  • 0 якщо це порушує властивості підказки.
  • Not 0 якщо б нічого не заважало йому бути підказкою.

1
@Emigna не думала, що це має значення, але виправлено!
Чарівна урва восьминога

1
Я хотів опублікувати відповідь дельтами, але про це не думав Á. Приємно!
Придатний

1
Ви можете зберегти 2 байти, використовуючи визначення значень truthy / falesy за допомогою ¥¹D7-Á+«P. Він отримує 0, коли в масиві є 0 або будь-яке інше значення.
Доступний

1
@ Доступний SMAART! Мега розумна людина, хороша робота.
Чарівна урва восьминога

6

R, 39 37 32 31 байт

all(q<-diff(x<-scan()),2*x+q-7)

Спробуйте в Інтернеті!

Бере вхід з stdin. Використовує diffдля перевірки того, чи однакові дві послідовні цифри; потім порівнює кожну цифру до 7 мінус попередню цифру. Повертається TRUEабо FALSE.

Збережено 5 байт завдяки Jarko Dubbeldam, а ще один завдяки JayCe.


Збереження відмінностей у деякій змінній, qа потім тестування 2*x+q-7замість c(0,x)!=c(7-x,0)економії кількох байт. Якщо x1 + x2 = 7тоді 2*x1 + diff(x1,x2) = 7. Перевірка 2*x+q - 7потім явно тестує !=0.
JAD

@JarkoDubbeldam Чудове спостереження, дякую! Я оновив рішення.
rturnbull


@JayCe Спасибі, я оновив відповідь зараз.
rturnbull

5

05AB1E , 10 байт

$ü+7ʹüÊ*P

Використовує кодування CP-1252 . Спробуйте в Інтернеті!


1
Argh !, чому я не подумав Ê: P Nice!
Емінья

Хм, так 1*[] = []але product(1, []) = 1. Це добре знати.
Емінья

@Emigna Власне, це помилка. Продукт []повинен бути 1.
Аднан

Так, я хотів, щоб це працювало так кілька разів раніше. Порядок операцій також має значення тут. )1*, )1s*і )1Pвсе []поки )1sPє 1.
Емінья

1
@Emigna Ааа, це тому, що продукт []видає помилку і відкидається. Ось чому це дає 1. Я спробую це виправити, коли повернусь додому.
Аднан

5

R, 49 44 байт

!any(rle(x<-scan())$l-1,ts(x)==7-lag(ts(x)))

Читає вхід зі stdin (розділений пробілом) та виводить TRUE/FALSE. Попередить, якщо вхід довжини один, але все ще працює.

Редагувати: зберегло пару байтів завдяки @rturnbull


Ви можете об'єднати all(x)&all(y)в , all(x,y)щоб зберегти кілька байт. Ви також можете перейти rle(x)$l==1до rle(x)$l-1, який потім поверне набір усіх, FALSEякщо xвін дійсний; потім переключіться на пізніше !=на ==і allдо !any. Це дозволить !any(rle(x<-scan())$l-1,ts(x)==7-lag(ts(x)))зекономити 5 байт. (PS, я написав альтернативне рішення , яке може вас зацікавити.)
rturnbull


4

JavaScript (ES6), 43 40 байт

Повернення 0/ true.

f=([k,...a],n=0)=>!k||k-n&&7-k-n&&f(a,k)

Тестові справи


На жаль, простий порт відповіді Retina - це лише 38 байт.
Ніл

@Neil Я думаю, що це насправді 37 сtest()
Арнольд

Вибачте, я випадково вставив новий рядок у лічильник байтів.
Ніл

4

Perl 6 , 22 байти

Використання регулярного вираження:

{!/(.)<{"$0|"~7-$0}>/}

Приймає дані як рядок. Натхненний відповіддю Рубі Рубі .
Як це працює:

  • / /: Зворотний вираз.
  • (.): Зрівняйте будь-який символ і захопіть його як $0.
  • <{ }>: Динамічно генеруйте субрегекс для відповідності в цій позиції.
  • "$0|" ~ (7 - $0): Підгерой, який ми генеруємо, це той, який відповідає лише попередній цифрі, або 7 мінус попередній цифрі (наприклад 5|2).
    Таким чином, загальний вираз буде відповідати, якщо він виявить недійсну послідовну пару цифр де завгодно.
  • {! }: Примусьте бути булевим (викликаючи відповідність регулярного вираження $_), заперечуйте його і перетворіть всю річ у лямбда (з неявним параметром $_).

Perl 6 , 38 байт

Використання обробки списку:

{all ([!=] 7-.[1],|$_ for .[1..*]Z$_)}

Приймає вхід як масив цілих чисел.
Як це працює:

  • .[1..*] Z $_: Складайте список вхідних даних зі зміщенням на одну версію себе, щоб створити список з 2-х кортежів послідовних цифр.
  • [!=] 7 - .[1], |$_: Для кожного з них перевірте, чи немає (7 - b) != a != b.
  • all ( ): Повертайте значення truthy чи фальш, залежно від того, чи всі ітерації циклу повернули True.

4

Пітон, 38 байт

f=lambda h,*t:t==()or 7>h^t[0]>0<f(*t)

Рекурсивна функція, яка приймає подібні аргументи f(1,2,3).

Це використовує розпакування аргументу для вилучення першого числа, hа решта в кортеж t. Якщо tпорожній, виведіть True. В іншому випадку скористайтеся біт-трюком Згарба, щоб перевірити, що перші два рулони не є несумісними. Потім переконайтеся, що результат також утримується на рекурсивному дзвінку на хвості.


4

Рубін, 34 байти

->s{!s[/[16]{2}|[25]{2}|[34]{2}/]}

2
ви можете поголити два байти, скориставшись строковим #[]методом:->s{!s[/[16]{2}|[25]{2}|[34]{2}/]}
Алексіс Андерсен

Я не знав, що ви можете використовувати його з регулярним виразом, дякую.
ГБ

4

JavaScript 61 43 байт

У коментарях згадувалося, що я не можу використовувати функції C # linq без включення оператора use, тому ось саме те саме в менших байтах, використовуючи стандартний JS ...

f=a=>a.reduce((i,j)=>i>6|i==j|i+j==7?9:j)<7

C #, 99 67 65 байт

Приймає введення як масив int a

// new solution using linq
bool A(int[]a){return a.Aggregate((i,j)=>i>6|i==j|i+j==7?9:j)<7;}
// old solution using for loop
bool A(int[]a){for(int i=1;i<a.Length;)if(a[i]==a[i-1]|a[i-1]+a[i++]==7)return false;return true;}

Пояснення:

// method that returns a boolean taking an integer array as a parameter
bool A(int[] a) 
{
    // aggregate loops over a collection, 
    // returning the output of the lambda 
    // as the first argument of the next iteration
    return a.Aggregate((i, j) => i > 6 // if the first arg (i) > than 6
    | i == j      // or i and j match
    | i + j == 7  // or i + j = 7
    ? 9   // return 9 as the output (and therefore the next i value)
    : j   // otherwise return j as the output (and therefore the next i value)
    ) 
    // if the output is ever set to 9 then it will be carried through to the end
    < 7; // return the output is less than 7 (not 9)
}

Я думаю , що це повинно бути обгорнуте в функції, або , може бути , лямбда (це C # є ті?) Крім того , ви можете заощадити кілька байт, повертаючи 0або 1замість falseабоtrue
DJMcMayhem

о, добре - перший пост про код гольфу. Я відредагую ...
Erresen

Без проблем. BTW, ласкаво просимо на сайт! :)
DJMcMayhem

@DJMcMayhem Виправте мене, якщо я помиляюся, але оскільки вимога виводу є truthy / falsey, тоді вихідні варіанти залежать від мови tl; dr 1/0 не є truthy / falsey в c #
JustinM - Відновіть Моніку

@Phaeze Ви вірні, що вони не truthy / falsey, але стандартні правила вводу- виводу meta.codegolf.stackexchange.com/questions/2447/… розраховують, що ви можете виводити, використовуючи вихідні коди, і які функції можуть виводити так само, як і програми. Я перейду на булеві, якщо потрібно, але це коштуватиме мені декількох укусів
Ерресен

3

> <> (Риба) 47 байт

0:i:1+?!v\!
   0n;n1< >
!?-{:-"0"/^
!? -{-$7:/^

Досить простий;

Рядок 1: перевірте, чи введено це число, якщо немає номера (EOF), то у нас є правда для друку інших чеків.

Рядок 2: результат друку.

Рядок 3: перетворіть вхід на число (ASCII 0 - з введення), а потім перевірте, чи він рівний попередньому вводу.

Рядок 4: перевірте, чи вхід є протилежною стороною штамп


3

Мозок-Flak 128 байт

(()){{}(({}<>)<>[({})])}{}([]){{{}}<>}{}([]){{}({}({})<>)<>([][()])}{}(<{}>)<>(([])){{}{}({}[(()()()){}()]){<>}<>([][()])}({}{})

Виходи 0 для фальси, або -7 для truthy.

Спробуйте в Інтернеті! (Truthy)
Спробуйте в Інтернеті! (Флейсі)

Пояснення (t означає верх, а s - секунду зверху):

(())                # push a 1 to get this loop started
{{}                 # loop through all pairs, or until 2 are equal
(({}<>)<>[({})])    # pop t, push t on the other stack, and t - s on this one
}{}                 # end loop and pop one more time
([])                # push the height of the stack
{                   # if the height isn't 0 (there were equal numbers)...
{{}}<>              # pop everything from this stack and switch
}                   # end if
{{}                 # for every pair on the stack: pop the height and...
({}({})<>)<>        # push t + s on the other stack leaving s on this one
([][()])            # push the height - 1
}                   # end loop when there is only 1 number left
{}(<{}>)<>          # pop t, pop s, push 0 and switch stacks
(([]))              # push the height twice
{                   # loop through every pair
{}{}                # pop the height and what was t - 7
({}[(()()()){}()])  # push t - 7
{<>}<>              # if t is not 0 switch stacks and come come back
                    # if t is 0 (ie, there was a pair that added to 7) just switch once
([][()])            # push height - 1
}                   # end loop
({}{})              # push t + s (either 0 + 0 or 0 + -7)


3

PHP, 63 байти

for($d=$argv[$i=1];$c=$argv[++$i];$d=$c)$d-$c&&$d+$c-7?:die(1);

приймає введення як список аргументів команди; закінчується 1(помилка), якщо введення недійсне, 0(ok), якщо дійсне.

Бігайте з -nr.

введення як аргумент рядка, 65 байт

for($d=($s=$argv[1])[0];$c=$s[++$i];$d=$c)$d-$c&&$d+$c-7?:die(1);

3

PowerShell , 57 44 41 байт

( Закреслено 44 все ще регулярно 44 )

0-notin($args|%{7-$_-$l-and$l-ne($l=$_)})

Спробуйте в Інтернеті!

(ОП уточнила, що приймати дані як окремі аргументи - це нормально - збережено 13 байт ... збережено ще 3 байти шляхом усунення $b)

Ми проходимо циклічно через введення $argsцифру за раз. Кожна цифра, ми переконалися , що $lАсти цифра -nВЗ eКачи до поточної цифрі $_, і що 7-$_-$lдеяке число , відмінне від нуля (що truthy). Ці булеві результати інкапсулюються в паренах і подаються в правий операнд -notinоператора, перевіряючи проти 0. Іншими словами, якщо Falseв циклі є якесь значення, то -notinбуде і воля False. Булевий залишений на конвеєрі, а вихід неявний.

Тривалий через $вимогу до імен змінних, і що булеві команди -ne -andє багатослівними в PowerShell. Ну добре.


3

Обробка, 93 92 90 байт

Змінено || на | : 1 байт збережено завдяки @ClaytonRamsey

Початок відліку назад: 2 байти збережено завдяки @IsmaelMiguel

int b(int[]s){for(int i=s.length;--i>0;)if(s[i-1]==s[i]|s[i-1]==7-s[i])return 0;return 1;}

Приймає введення як масив ints, вихід 1для true або0 for false.

Безумовно

int Q104044(int[]s){
  for(int i=s.length;--i>0;)
    if(s[i-1]==s[i]|s[i-1]==7-s[i])
      return 0;
  return 1;
}

Зазвичай Java дозволяє | замість || якщо ви хочете зберегти байт.
Клейтон Рамзі

@ClaytonRamsey Я не знаю, чому я не думав про це, дякую!
Kritixi Lithos

Я знайшов ще одну. Ви можете скоротити використання віддачі з третинним оператором
Клейтон Рамзі

@ClaytonRamsey return 0- Всередині if-оператора, поки return 1немає. Я не бачу, як це можливо, якщо ви не маєте іншої ідеї
Kritixi Lithos

2
Golfed it! Yipee! (nobody's going to read these summaries so why not have fun :)<- Я читав, порівнюючи те, що маєш, з тим, що мав.
Ісмаель Мігель

3

С 47 44 байти

F(char*s){return!s[1]||(*s^s[1])%7&&F(s+1);}

приймає рядок цифр (або нульовий завершений масив байтів)

Пояснення

F(char*s){

відповідно до стандартного intтипу повернення мається на увазі. (збереження 4 байтів)

return безумовне повернення, оскільки це рекурсивна функція

використовуючи ярлик оцінки:

!s[1]||якщо другий символ є нульовим, поверніть істинне

((*s^s[1])%7&& якщо перші два статути не є юридичними помилками

F(s+1)) перевірити решту рядка таким же чином

це заплутане вираз

*sє перший персонаж s[1]- другий

*s^s[1] ексклюзив - або їх разом, якщо вони однакові, результат дорівнює 0, якщо вони додають до 7, результат - 7, (якщо вони відрізняються і не додають до 7, результат становить від 1 до 6 включно)

так (*s^s[1])%7це нуль для поганого введення, а не нуль інакше, таким чином, помилково, якщо ці 2 символи є поганими, а істинно інакше

коментар: оскільки цей виклик функції використовує лише кінцеву рекурсію (лише остання заява є рекурсивним викликом), оптимізатор може перевести рекурсію в цикл, це щаслива консистенція і, очевидно, не вартує жодної оцінки гольфу, але в реальному слові дозволяє обробляти рядки будь-якої довжини без вичерпання стека.


1
Щодо вашого, !((*s^s[1])%7)я думаю, ви цього не хочете !. Нульові значення для поганого введення були б помилковими, тому ви хочете повернути ложну, коли вона погана.
nmjcman101

2

Пітон, 71 байт

f=lambda s:len(s)<2or(s[0]!=s[1]and int(s[0])!=7-int(s[1]))and f(s[1:])

Використовується рекурсивний підхід.

Пояснення:

f=lambda s:                                                              # Define a function which takes an argument, s
           len(s)<2 or                                                   # Return True if s is just one character
                      (s[0]!=s[1]                                        # If the first two characters matches or...
                                 and int(s[0])!=7-int(s[1])              # the first character is 7 - the next character, then return False
                                                           )and f(s[1:]) # Else, recurse with s without the first character

скажіть, що вхід - це список вкладень, і тоді вам не потрібні касти.
Ясен


2

MATL , 9 байт

dG2YCs7-h

Вхід - це масив чисел, що представляють цифри.

Вихід - це не порожній масив, який є істинним, якщо всі його записи не нульові, а помилковим - інакше (докладніше про критерій MATL щодо правдивості та хибності читайте тут ).

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Пояснення

d     % Take input implicitly. Consecutive differences
G     % Push input again
2YC   % Overlapping blocks of length 2, arranged as columns of a matrix
s     % Sum of each column
7-    % Subtract 7, element-wise
h     % Concatenate horizontally. Implicitly display

Чи можливо / призначено додати деякі нові функції MATLAB до MATL?
rahnema1

@ rahnema1 Так, деякі імена функцій наразі не використовуються. Однак я схильний бути вибірковим і додаю лише ті, які, на мою думку, будуть використовуватися часто. Якщо у вас є якісь пропозиції, ми можемо обговорити їх у чаті MATL :-)
Луїс Мендо

@ rahnema1 Якщо ви думаєте movsum, вже є conv2(що включає conv); дивіться Y+іZ+
Луїс Мендо

2

C # (з Linq) 90 81 73 71 69 68 Байт

using System.Linq;n=>n.Aggregate((p,c)=>p<9|c==p|c==103-p?'\b':c)>9;

Пояснення:

using System.Linq;           //Obligatory import
n=>n.Aggregate((p,c)=>       //p serves as both previous character in chain and error flag
    p<9                      //8 is the error flag, if true input is already invalid            
        |c==p            
            |c==103-p        //103 comes from 55(7) + 48(0)
                ?'\b'       //'\b' because it has a single digit code (8)
                    :c)      //valid so set previous character, this catches the first digit case as well
                        >8;  //as long as the output char is not a backspace input is valid

2

C, 81 байт, становив 85 байт

int F(int *A,int L){int s=1;while(--L)s&=A[L]!=A[L-1]&A[L]!=(7-A[L-1]);return s;}

Вхід - це масив цілих чисел A довжиною L. Повертає 1 для істинного та 0 для помилкового. Вхід перевіряється від кінця до початку, використовуючи вхідну довжину L як індекс масиву.


int не обов’язково на початку, ви можете зберегти 4 байти.
Ясен

int s=1;можна оголосити поза функцією, як s=1;для іншого 4.
nmjcman101

2

Хаскелл, 37 байт

f(a:b:c)=a+b/=7&&a/=b&&f(b:c)
f _=1<2

Приклад використання: f [1,5,2]-> False.

Проста рекурсія. Базовий регістр: єдиний список елементів, який повертається True. Рекурсивний випадок: нехай aі bбудуть першими двома елементами вхідного списку та cрештою. Всі наступні умови повинні виконуватися: a+b/=7, a/=bі рекурсивний виклик з aвідкинуто.


2

JavaScript, 40 байт

f=i=>i.reduce((a,b)=>a&&a-b&&a+b-7&&b,9)

Скористається функцією JavaScript, яка &&поверне останнє значення, яке розібрано (або фальшивий або останній термін). 0передається разом, якщо він не відповідає умовам, а попередній термін передається інакше. 9 гарантує, що він починається з правдоподібного значення.





1

Пакетна, 102 байти

@set s=%1
@set/an=0%s:~0,2%,r=n%%9*(n%%7)
@if %r%==0 exit/b
@if %n% gtr 6 %0 %s:~1%
@echo 1

Безголівки:

@echo off
rem grab the input string
set s=%1
:loop
rem convert the first two digits as octal
set /a n = 0%s:~0,2%
rem check for divisibility by 9 (011...066)
set /a r = n %% 9
rem exit with no (falsy) output if no remainder
if %r% == 0 exit/b
rem check for divisibility by 7 (016...061)
set /a r = n %% 7
rem exit with no (falsy) output if no remainder
if %r% == 0 exit/b
rem remove first digit
set s=%s:~1%
rem loop back if there were at least two digits
if %n% gtr 6 goto loop
rem truthy output
echo 1
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.