Написать эффект домино

25

Используя наименьшее количество символов Юникода, напишите функцию, которая принимает три параметра:

  • Общее количество домино
  • nпострадавшее домино
  • Свергнуть направление пораженного домино ( 0или Lслева, 1или Rсправа)

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

Вы должны вывести домино с |изображением стоящего домино и \и с /изображением домино, свергнутых слева и справа соответственно.

Примеры

10, 5, 1должен вернуться ||||//////
6, 3, 0должен вернуться\\\|||

rybo111
источник
Третий параметр должен быть строкой или bool / int будет делать 0: влево, 1: вправо?
user80551
Ваш пример предполагает, что, если есть 10 домино, и 5 выбиты правильно, мы должны показать шесть из десяти сбитых домино.
алгоритмический
1
@algorithmshark Я думаю, что мы должны показать результат, если пятое домино выбито правильно.
user80551
@ rybo111 Можете ли вы позволить третьему параметру быть int, поскольку это может сделать операции сравнения короче. Просто if(third_parameter)вместоif(third_paramter=='l')
user80551
Можем ли мы выбрать порядок параметров?
Джастин

Ответы:

14

Рубин, 38 (46) символов

e=->n,k,r{k-=r;'\|'[r]*k+'|/'[r]*n-=k}

Эта функция принимает направление как целое число ( 1справа, 0слева). Функция, которая принимает строку, на 8 символов длиннее:

d=->n,k,r{n-=k;r<?r??\\*k+?|*n :?|*~-k+?/*-~n}

Примеры использования:

puts e[10, 5, 1] # or d[10, 5, 'r']
||||//////
puts e[10, 5, 0] # or d[10, 5, 'l']
\\\\\|||||
Ventero
источник
почему во втором примере осталось только 5 домино?
Клайд Лобо
1
@ClydeLobo Потому что вы начинаете с позиции 5 и стучите в домино слева, которое, в свою очередь, опрокидывает 4 домино слева, в общей сложности 5. В первом примере, начиная с позиции 5, опрокидывается 6 домино: в позиции 5 плюс 5 справа.
Вентеро
8

Хаскелл, 70

f R i l=(i-1)#'|'++(l-i+1)#'/'
f L i l=i#'\\'++(l-i)#'|'
(#)=replicate

при условии что тип направление , который имеет конструкторы R и L .

гордый хаскеллер
источник
8

J - 32 26 символов

J не может обрабатывать более двух аргументов без использования списка, и он не может обрабатывать неоднородные списки без упаковки. Таким образом, иметь входные данные в виде списка из трех целых чисел идеально. Порядок параметров обратен стандартному: 0 для левого или 1 для правого, затем положение, затем общее количество домино. Причина этого заключается в том, что J в конечном итоге будет проходить их справа налево.

{`(('|/\'{~-@>:,:<:)1+i.)/

Вот что происходит. F`G/применяется к списку x,y,zбудет оценивать x F (y G z). y G zконструирует оба возможных способа, которые домино может опрокинуть, а затем Fиспользует, xчтобы выбрать, какой из двух использовать.

Ниже приведен обзор J REPL, который объясняет, как эта функция строится вместе: строки с отступом вводятся в REPL, а ответы располагаются заподлицо с левым полем. Напомним, что J оценивается строго справа налево, если нет паренов:

   1 ] 3 (]) 10            NB. ] ignores the left argument and returns the right
10
   1 ] 3 (] 1+i.) 10       NB. hook: x (F G) y  is  x F (G y)
1 2 3 4 5 6 7 8 9 10
   1 ] 3 (>: 1+i.) 10      NB. "greater than or equal to" bitmask
1 1 1 0 0 0 0 0 0 0
   1 ] 3 (-@>: 1+i.) 10    NB. negate
_1 _1 _1 0 0 0 0 0 0 0
   1 ] 3 (<: 1+i.) 10      NB. "less than or equal to"
0 0 1 1 1 1 1 1 1 1
   1 ] 3 ((-@>:,:<:)1+i.) 10          NB. laminate together
_1 _1 _1 0 0 0 0 0 0 0
 0  0  1 1 1 1 1 1 1 1
   1 ] 3 (('|/\'{~-@>:,:<:)1+i.) 10   NB. turn into characters
\\\|||||||
||////////
   1 { 3 (('|/\'{~-@>:,:<:)1+i.) 10   NB. select left or right version
||////////
   {`(('|/\'{~-@>:,:<:)1+i.)/ 1 3 10  NB. refactor
||////////
   {`(('|/\'{~-@>:,:<:)1+i.)/ 0 3 10
\\\|||||||

За счет нескольких символов мы можем сделать порядок стандартным: просто добавьте @|.в конец функции:

   |. 10 3 1
1 3 10
   {`(('|/\'{~-@>:,:<:)1+i.)/@|. 10 3 1
||////////

Однако адаптация этого к работе со строковым аргументом для направления будет намного более дорогостоящей.

algorithmshark
источник
Я знаю, что прошло много времени с тех пор, как вы написали этот ответ, но его структура очень крутая. Мне очень нравится, как вы использовали герунды, а /также то, как вы строите два выхода и выбираете нужный. Думаю, мне не хватает признания, которого оно заслуживает.
Коул
Что сказал @cole, я был в восторге.
FrownyFrog
7

PowerShell, 66

filter d($n,$k,$d){"$('\|'[$d])"*($k-$d)+"$('|/'[$d])"*($n-$k+$d)}

Вероятно, та же идея, что и у всех остальных.

  • Принимает 0 или 1 в качестве параметра направления (для левого и правого соответственно)
детеныш
источник
6

Golfscript (44 53 )

Моя первая в мире программа Golfscript. Это заняло у меня больше времени, чем следовало бы, и, вероятно, это можно сделать более умным, более кратким способом (я уверен, что кто-то докажет это :)):

:d;:j;:^,{:x j<d&'\\'{x^j)->d!&'/''|'if}if}%

Пример ввода есть 10 5 0.

Ungolfed:

:d;:j;:^      # save input in variables and discard from stack, except total length ^
,             # create an array of numbers of length ^
{             # start block for map call
  :x          # save current element (= index) in variable
  j<          # check whether we are left of the first knocked over domino
  d           # check whether the direction is to the left
  &           # AND both results
  '\\'        # if true, push a backslash (escaped)
  {           # if false, start a new block
    x^j)->    # check whether we are on the right of the knocked over domino
    d!        # check whether the direction is to the right
    &         # AND both results
    '/'       # if true, push a slash
    '|'       # if false, push a non-knocked over domino
    if
  }
  if
}%            # close block and call map
Инго Бюрк
источник
1
Доказательство сделано ;-), хотя я еще не доволен своим решением.
Говард
1
Некоторые советы: Вы можете dбыть 0/ 1вместо 'l'/ , 'r'который дает вам несколько более короткий код. В противном случае, если вы храните d'l'=в переменной oyu может использовать его вместо второго сравнения с d. В этом термине x i jвы можете сохранить оба пробела, если вместо имени используете не алфавитно-цифровое имя переменной i.
Говард
@Howard Спасибо за советы! Я выбрал 'l'/ 'r'потому что в то время я еще не видел, что мы можем использовать целые числа. Не буквенно-цифровой трюк ловкий, спасибо! Возможно я обновлю ответ позже.
Инго Бюрк
4

GolfScript, 28 23 символа

'\\'@*2$'|/'*$-1%1>+@/=

Аргументы сверху стека, попробуйте онлайн :

> 10 5 1
||||//////

> 10 5 0
\\\\\|||||
Говард
источник
Удивительно. Люблю учиться на всех этих решениях для игры в гольф :)
Ingo Bürk
4

Питон - 45 52

Это требует 1для правой и 0левой стороны.

x=lambda n,k,d:'\\|'[d]*(k-d)+"|/"[d]*(n-k+d)

Вот версия, которая принимает rи lправильно, на 58 :

def x(n,k,d):d=d=='r';return'\\|'[d]*(k-d)+"|/"[d]*(n-k+d)

Некоторые примеры использования ...

>>> print(x(10,3,0))
\\\|||||||
>>> print(x(10,3,1))
||////////
>>> print(x(10,5,1))
||||//////
>>> print(x(10,5,0))
\\\\\|||||
>>> print(x(10,3,0))
\\\|||||||
cjfaure
источник
4

JS (ES6) - 79 74 72 65 62

спасибо @nderscore!

Третий параметр является логическим (0: слева / 1: справа)

d=(a,b,c)=>"\\|"[a-=--b,c].repeat(c?b:a)+"|/"[c].repeat(c?a:b)

// Test
d(10,3,1); // => "||////////"
d(10,3,0); // => "\\\\\\\\||"
XEM
источник
1
эта запись может быть справочной картой для ECMAScript 6: D
be
@bebe хаха, и это даже не окончательная форма. ES6 может быть очень грязным.
xem
1
65:d=(a,b,c)=>"\\"[r="repeat"](!c&&a-b+1)+"|"[r](--b)+"/"[r](c&&a-b)
nderscore
1
отличный! Я также нашел эту сумасшедшую вещь, но она длиннее (67): d = (a, b, c, d = a-b + 1) => "\\ |" [c] .repeat (c? B-1: d ) + "| /" [c] .repeat (c? d: b-1)
xem
Я не думаю, что повторный псевдоним стоит. [r='repeat'][r]15 символов .repeat.repeat14 символов
edc65
3

Python2 / 3 - 54

Последнее добавленное правило было довольно неплохо (0/1 вместо 'l' / 'r'). Сделано мое фактически меньше, чем существующее решение Python. 0 слева, 1 справа

def f(a,b,c):d,e='\|/'[c:2+c];h=b-c;return d*h+e*(a-h)

# Usage:
print(f(10,5,1)) # => ||||//////
print(f(10,5,0)) # => \\\\\|||||
pseudonym117
источник
3

Haskell , 42 байта

(n%k)b=["\\|/"!!(b-div(k-b-c)n)|c<-[1..n]]

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

Принимает входной сигнал как (%) n k bдля nдомино, k-м домино свергнутого, направление b.

Находит символ в каждой позиции в cдиапазоне от 1до n, используя арифметическое выражение для вычисления индекса символа 0, 1 или 2.

Тестовые случаи взяты отсюда .


Haskell , 44 байта

(n%k)b=take n$drop(n+n*b+b-k)$"\\|/"<*[1..n]

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

Интересная стратегия, которая получилась чуть дольше. Создает строку "\\|/"<*[1..n]с nпоследовательными копиями каждого символа, затем берет фрагмент nсмежных символов с начальным положением, определенным арифметически.

XNOR
источник
2

Python 2,7, 68 65 61 59 58 символов

Используйте d=1для левого и d=0правого

f=lambda a,p,d:['|'*(p-1)+'/'*(a-p+1),'\\'*p+'|'*(a-p)][d]

Примечание: спасибо @TheRare за дальнейшую игру в гольф.

user80551
источник
1
Почему нет d and'\\'...or'/'...?
Seequ
Вы также можете сделать('\\'...,'/'...)[d]
seequ
@TheRare Мне нужно два из этих списков.
user80551
Я так не думаю. f=lambda a,p,d:('|'*(p-1)+'/'*(a-p+1),'\\'*p+'|'*(a-p))[d]
Seequ
@TheRare Also, I don't think your code works when falling left.Не могли бы вы дать контрольный пример, чтобы доказать?
user80551
2

Javascript, 46 знаков

Похоже на обман делать 0 = l и 1 = r, но есть. Сократил это с небольшой рекурсией.

f=(a,p,d)=>a?'\\|/'[(p-d<1)+d]+f(a-1,p-1,d):''

редактировать: пропустил очевидный персонаж

user29119
источник
2

JavaScript (ES6) 61 63

Править Это было глючно - позор мне.

Не сильно отличается от @xem, но нашел его сам и короче. Параметр d равен 0/1 для левого / правого

F=(a,p,d,u='|'.repeat(--p),v='\\/'[d].repeat(a-p))=>d?u+v:v+u

Тест в консоли Firefox

for(i=1;i<11;i+=3) console.log('L'+i+' '+F(10,i,0) + ' R'+i+' '+ F(10,i,1))

Выход

L1 \\\\\\\\\\ R1 //////////
L4 \\\\\\\||| R4 |||///////
L7 \\\\|||||| R7 ||||||////
L10 \||||||||| R10 |||||||||/
edc65
источник
1
Должно ли это быть --p?
nderscore
@nderscore да, должно быть, неверные параметры, глупый я.
edc65
2

Perl, 67 65 персонажей

sub l{($t,$p,$d)=@_;$p-=$d;($d?'|':'\\')x$p.($d?'/':'|')x($t-$p)}

Назначьте первые три параметра (сумма, позиция, направление в виде целого числа [0 слева, 1 справа]). Дополнения уходят в эфир. Вычтите 1 из позиции, если мы идем направо, так что домино в позиции X также перевернуто.

titanofold
источник
1
заменить $p--if$dс $p-=$dпотерять два символа :)
китайский Perl готику
2

R , 75 68 61 57 байт

Анонимная функция. Я выложу более полное объяснение, если есть интерес.

function(t,n,d)cat(c("\\","|","/")[(1:t>n-d)+1+d],sep="")

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

rturnbull
источник
2

Haskell , 51 байт

f a b c=("\\|"!!c<$[1..b-c])++("|/"!!c<$[b-c..a-1])

a= количество домино, b= 1 индекс касания, c= направление ( 0слева и 1справа).

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

Макс ехлаков
источник
Определение оператора инфиксного работает более двух входов: (a#b)c= ....
Лайкони
1

PHP - 64

function f($a,$b,$c){for($w='\|/';++$i<=$a;)echo$w[$c+($i>$b)];}

Простой цикл и повторяющий характер.

Создает Notice: Undefined variable: i, вот еще одна версия, скрывающая ошибку (65 символов):

function f($a,$b,$c){for($w='\|/';@++$i<=$a;)echo$w[$c+($i>$b)];}

И версия без каких-либо ошибок (69 символов):

function f($a,$b,$c){for($w='\|/',$i=0;++$i<=$a;)echo$w[$c+($i>$b)];}

Другие функции в PHP:

sprintf/ printfнабивка

function f($a,$b,$c){printf("%'{${0*${0}=$c?'|':'\\'}}{$a}s",sprintf("%'{${0*${0}=$c?'/':'|'}}{${0*${0}=$a-$b+$c}}s",''));}

заполнение через str_pad/ str_repeatфункции

function f($a,$b,$c){$f='str_repeat';echo$f($c?'|':'\\',$b-$c).$f($c?'/':'|',$a-$b+$c);}
function f($a,$b,$c){echo str_pad(str_repeat($c?'|':'\\',$b-$c),$a,$c?'/':'|');}

используя как printfи str_repeatфункции

function f($a,$b,$c){printf("%'{${0*${0}=$c?'|':'\\'}}{$a}s",str_repeat($c?'/':'|',$a-$b+$c));}
function f($a,$b,$c){$w='\|/';printf("%'$w[$c]{$a}s",str_repeat($w[$c+1],$a-$b+$c));}
Nplay
источник
1

Скала 75 персонажей

def f(l:Int,p:Int,t:Char)=if(t=='l')"\\"*p++"|"*(l-p) else "|"*(l-p):+"/"*p
JCW
источник
1

CJam - 20

q~
:X-_"\|"X=*o-"|/"X=*

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

Попробуйте это на http://cjam.aditsu.net/

Примеры:

12 4 1
|||/////////

8 5 0
\\\\\|||

Объяснение:

:Xсохраняю последний параметр (0/1 направления) в переменной X
-вычитает X от цепного над положением, получение длиной первой последовательности символов (назовем его L)
_делает копию L
"\|"X=получает символ использовать первый: \для X = 0 и |для X = 1
*повторяет, что символ L раз
oпечатает строку, удаляя ее из стека,
-вычитает L из числа домино, получая длину второй последовательности символов (назовем это R),
"|/"X=переводит символ в используйте следующее: |для X = 0 и /для X = 1
*повторяет этот символ R раз

aditsu
источник
1

Обыкновенный Лисп

Это не победит в кодовом гольфе, но оно подчеркивает директиву формата оправдания Common Lisp:

(lambda (n p d &aux (x "\\|/"))
   (format t "~v,,,v<~v,,,v<~>~>" n (aref x d) (+ d (- n p)) (aref x (1+ d))))

Арифметика не плохая: nэто общее количество домино; pпозиция первого свергнутого домино; dлибо 0либо 1, либо представляет левый и правый (как разрешено в комментариях) и используется в качестве индекса в x; xявляется строкой \, |и /. Строка формата использует две (вложенные) директивы выравнивания, каждая из которых допускает добавочный символ. Таким образом:

(dotimes (d 2)
  (dotimes (i 10)
    ((lambda (n p d &aux (x "\\|/"))
       (format t "~v,,,v<~v,,,v<~>~>" n (aref x d) (+ d (- n p)) (aref x (1+ d))))
     10 (1+ i) d)
    (terpri)))

\|||||||||
\\||||||||
\\\|||||||
\\\\||||||
\\\\\|||||
\\\\\\||||
\\\\\\\|||
\\\\\\\\||
\\\\\\\\\|
\\\\\\\\\\
//////////
|/////////
||////////
|||///////
||||//////
|||||/////
||||||////
|||||||///
||||||||//
|||||||||/
Джошуа Тейлор
источник
1

PHP, 89 символов

function o($a,$p,$d){for($i=0;$i<$a;$i++)echo$d==0?($i+1>$p)?'|':'\\':($i+1<$p?'|':'/');}

Просто потому, что я люблю PHP.

РЕДАКТИРОВАТЬ: следующий код делает то же самое.

function dominoes ($number, $position, $direction) {
    for ($i=0; $i<$number; $i++){
        if ($direction==0) {
            if (($i+1) > $position) {
                echo '|';
            } else {
                echo '\\';
            }
        } else {
            if (($i+1) < $position) {
                echo '|';
            } else {
                echo '/';
            }
        }
    }
}
TribalChief
источник
Есть более подробная версия?
Мартин
1
@ Martijn, я отредактировал свой пост, чтобы включить один.
TribalChief
Теперь я вижу, что он делает. Ничего особенного, но +1 :)
Мартейн
Благодарность! Решения @NPlay выглядят причудливо, хотя!
TribalChief
пара советов по игре в гольф: 1) Ненужные скобки в ($i+1>$p). 2) Переписать ваше троичное выражение, чтобы $d?($i+1<$p?'|':'/'):$i+1>$p?'|':'\\'сохранить еще 3 байта. Или просто удалить ==0и инвертировать направления. 3) С помощью $i++<$aвы можете удалить $i++из пост условия и использовать $iвместо $i+1(-6 байт). 4) $i=0не обязательно; но вам придется подавить уведомления (опция --n), если вы удалите ее (-4 байта).
Тит
1

05AB1E , 19 байтов

αα©„\|³è×¹®-„|/³è×J

У меня все еще есть ощущение, что он немного длинный, но он работает .. И лучше, чем первоначальное 23-байтовое решение, которое я имел с конструкцией if-else, которую я быстро отбросил ..

Порядок ввода такой же, как в задании: общая длина, индекс, 1/0 для левого / правого соответственно.

Попробуйте онлайн или проверьте оба теста .

Объяснение:

α                     # Take the absolute difference of the first two (implicit) inputs
                      #  i.e. 10 and 5 → 5
                      #  i.e. 6 and 3 → 3
 α                    # Then take the absolute difference with the third (implicit) input
                      #  i.e. 5 and 1 → 4
                      #  i.e. 3 and 0 → 3
  ©                   # Store this number in the register (without popping)
   \|                # Push "\|"
      ³è              # Use the third input to index into this string
                      #  i.e. 1 → "|"
                      #  i.e. 0 → "\"
        ×             # Repeat the character the value amount of times
                      #  i.e. 4 and "|" → "||||"
                      #  i.e. 3 and "\" → "\\\"
         ¹®-          # Then take the first input, and subtract the value from the register
                      #  i.e. 10 and 4 → 6
                      #  i.e. 6 and 3 → 3
            „|/       # Push "|/"
               ³è     # Index the third input also in it
                      #  i.e. 1 → "/"
                      #  i.e. 0 → "|"
                 ×    # Repeat the character the length-value amount of times
                      #  i.e. 6 and "/" → "//////"
                      #  i.e. 3 and "|" → "|||"
                  J   # Join the strings together (and output implicitly)
                      #  i.e. "||||" and "//////" → "||||//////"
                      #  i.e. "///" and "|||" → "///|||"
Кевин Круйссен
источник
0

С ++ 181

#define C(x) cin>>x;
#define P(x) cout<<x;
int n,k,i;char p;
int main(){C(n)C(k)C(p)
for(;i<n;i++){if(p=='r'&&i>=k-1)P('/')else if(p=='l'&&i<=k-1)P('\\')else P('|')}
return 0;}
bacchusbeale
источник
1
Вам на самом деле не нужно явно return 0из main.
zennehoy
Он не компилируется для меня, потому что cin и cout не находятся в глобальном пространстве имен - какой компилятор вы используете? Кроме того, C(n)>>k>>pбудет коротким, чем C(n)C(k)C(p)не так? И если определение для P () может привести к строковому аргументу, разве это не сохранит символы для всех кавычек? И когда вы сравниваете p с 'l' и 'r': 0 и 1 будут короче - в частности> 0 вместо == 'r' и <1 вместо == 'l' (при условии, что вы в порядке, используя числа вместо r / l - если нет, <'r' по-прежнему короче == 'l', а> 'l' по-прежнему короче == 'r')
Джерри Иеремия
@JerryJeremiah для cin и cout нужно "используя пространство имен std".
bacchusbeale
Я знаю, но поскольку он используется только в два раза, он укорачивает функции. Ни один из способов не работает на моем компиляторе без включения.
Джерри Иеремия
0

PHP - 105,97 , 96

 function a($r,$l,$f){$a=str_repeat('|',$l-$f);$b=str_repeat($r?'/':'\\',$f);echo$r?$a.$b:$b.$a;}

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

a(true,10,4);  -> \\\\||||||
a(false,10,5); -> |||||/////
a(false,10,2); -> ||||||||//
Мартейн
источник
0

Javascript, 81 85 символов

функция e (a, b, c) {l = 'repeat'; d = '|' [l] (- a-b ++); return c> 'q'? d + "/" [l] (b): "\\" [л] (б) + d}

Первый раз попробовал Codegolf, было весело, спасибо :)

Мат
источник
Также можно изменить функцию, чтобы она была функцией ES6, так как повтор строки - ES6 (не работает в Chrome).
Мэтт
0

JavaScript - 85 символов

function d(a,b,c){for(r=c?"\\":"/",p="",b=a-b;a--;)p+=c?a<b?"|":r:a>b?"|":r;return p}

1 = слева, 0 = справа

d(10,3,1)
\\\|||||||
d(10,3,0)
||////////
d(10,7,1)
\\\\\\\|||
d(10,7,0)
||||||////
Matt
источник
0

Clojure, 81 символ

(defn g[a,p,d](apply str(map #(nth "\\|/"(+(if(>= % (- p d)) 1 0) d))(range a))))
user29119
источник
0

vb.net (~ 75с)

Dim f=Function(l,p,d)(If(d="l",StrDup(p,"\"),"")& StrDup(l-p-If(d="l",1,0),"|")).PadRight(l,"/")
Адам Спейт
источник