Утвердить Случайные Die Tippers


33

Почти шесть лет назад коллега-член PPCG steenslag опубликовал следующую задачу:

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

Пример желаемого результата:

1532131356

Итак, теперь, когда все совершенно забыли об этом и победный ответ давно принят, мы напишем программу для проверки последовательностей опрокидывания, генерируемых представленными решениями. (Это имеет смысл. Просто притворись, что это так.)

Вызов

Ваша программа или функция имеет такую ​​последовательность, как 1532131356. Убедитесь, что каждая последующая цифра:

  • Не равно предыдущему разряду
  • Не равно 7 минус предыдущая цифра

(Вам не нужно проверять первую цифру.)

правила

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

Применяются стандартные правила ввода / вывода и лазейки .

Контрольные примеры

Truthy

1353531414
3132124215
4142124136
46
4264626313135414154
6
2642156451212623232354621262412315654626212421451351563264123656353126413154124151545145146535351323
5414142

Falsey

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

    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 байта больше :(
notjagan

Какое умное использование уменьшает, передавая каждое значение к следующему шагу.
xnor

9

Python, 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 байта за умную идею Osable об использовании продукта.

¥¹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
Я хотел опубликовать ответ с дельтами, но я не думал о Á. Ницца!
Osable

1
Вы можете сохранить 2 байта, используя определение истинных / ложных значений с помощью ¥¹D7-Á+«P. Он возвращает 0, когда в массиве есть 0 или любое другое значение в противном случае.
Osable

1
@Osable SMAART! Мега умный человек, хорошая работа.
Волшебная Урна Осьминога

6

R, 39 37 32 31 байт

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

Попробуйте онлайн!

Принимает ввод от стандартного ввода. Используется, 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
Аааа! Почему я не подумал Ê: P Хорошо !
Эминья

Хм, так , 1*[] = []но product(1, []) = 1. Это хорошо знать.
Эминья

@ Emigna На самом деле, это ошибка. Произведение []должно быть 1.
Аднан

Да, я бы хотел, чтобы это работало несколько раз раньше. Порядок операций также имеет значение здесь. )1*, )1s*И )1Pвсе в []то время как )1sPэто 1.
Emigna

1
@ Emigna Ааа, это потому, что произведение []дает ошибку и отбрасывается. Вот почему он дает 1. Я постараюсь это исправить, когда вернусь домой.
Аднан

5

R, 49 44 байта

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

Читает входные данные из стандартного ввода (разделенные пробелом) и выводит 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 байт.
Нил

@ Нил Я думаю, что на самом деле 37 сtest()
Арно

Извините, я случайно вставил новую строку в счетчик байтов.
Нил

4

Perl 6 , 22 байта

Используя регулярное выражение:

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

Принимает ввод в виде строки. Вдохновленный ответом Ruby от GB .
Как это работает:

  • / /: Регулярное выражение
  • (.): Сопоставить любой символ и захватить его как $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 ( )Возвращает истинное или ложное значение в зависимости от того, вернули ли все итерации цикла значение True.

4

Python, 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}/]}
Алексис Андерсен

Я не знал, что вы можете использовать его с регулярным выражением, спасибо.
GB

4

JavaScript 61 43 байта

В комментариях упоминалось, что я не могу использовать функции C # linq без включения оператора using, так что вот то же самое в меньшем количестве байтов при использовании стандартного 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

Нет проблем. Кстати, добро пожаловать на сайт! :)
DJMcMayhem

@DJMcMayhem Поправьте меня, если я ошибаюсь, но поскольку требование вывода - это истина / ложь, то параметры вывода зависят от языка tl; др. 1/0 не соответствуют истине / ложности в c #
ДжастинM - Восстановить Монику

@Phaeze Вы правы, что они не правдивые / фальшивые, но стандартные правила ввода-вывода meta.codegolf.stackexchange.com/questions/2447/… считают, что вы можете выводить, используя коды выхода, и что функции могут выводить так же, как программы. При необходимости я вернусь к логическим значениям, но это будет стоить мне нескольких укусов
Erresen

3

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

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

Довольно просто;

Строка 1: проверить, введено ли число, если нет номера (EOF), то у нас есть правдивый вывод на печать других проверок.

Строка 2: результат печати.

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

Строка 4: проверьте, находится ли вход на противоположной стороне матрицы.


3

Brain-Flak 128 Bytes

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

Выходы 0 для фальси или -7 для правды.

Попробуйте онлайн! (Правда)
Попробуйте онлайн! (Flasey)

Пояснение (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 (ок), если действителен.

Бежать с -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=$_)})

Попробуйте онлайн!

(OP пояснил, что принимать входные данные в качестве отдельных аргументов - это нормально - сохранено 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;}

Принимает ввод в виде массива целых чисел, вывод 1для true или 0для false.

Ungolfed

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 Я не знаю, почему я не подумал об этом, спасибо!
Критиси Литос

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

@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]||если второй символ nul, верните true

((*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

Python, 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 для true и 0 для false. Входные данные проверяются от конца до начала, используя входную длину L в качестве индекса массива.


int необязательно в начале, вы можете сохранить 4 байта.
Ясен

int s=1;может быть объявлено вне функции как s=1;для другого 4.
nmjcman101

2

Haskell, 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

Ungolfed:

@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.