Напишіть ефект доміно


25

Використовуючи найменші символи Unicode, запишіть функцію, яка приймає три параметри:

  • Загальна кількість доміно
  • nй постраждало доміно
  • Зверніть напрямок ураженого доміно ( 0або Lзліва, 1або Rсправа)

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

Вам слід виводити доміно, |представляючи стояче доміно \та /представляючи доміно, згорнуте ліворуч та праворуч відповідно.

Приклади

10, 5, 1повинен повернутися ||||//////
6, 3, 0повинен повернутися\\\|||


Чи повинен бути третій параметр рядком чи буде 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']
\\\\\|||||

чому у другому прикладі лишилося лише 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 char

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
||////////

Однак пристосування цього до роботи зі строковим аргументом для напрямку буде значно дорожчим.


Я знаю, що минув час, коли ви написали цю відповідь, але спосіб її структурування дуже класний. Мені дуже подобається, як ви використали заслінки, а /також спосіб побудови двох виходів і вибір потрібного. Я думаю, мені здається, що цього не вистачає визнання, яке воно заслуговує.
Коул

Що сказав @cole, я був здивований
FrownyFrog

7

PowerShell, 66

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

Напевно, таку саму ідею мали всі інші.

  • Приймає або 0, або 1, як параметр напрямку (ліворуч та праворуч відповідно)

6

Гольфскрипт (44 53 )

Моя перша в історії програма Golfscript. Взяв мене довше, ніж повинен був, і, ймовірно, це можна зробити більш розумним, стислим (я впевнений, що хтось доведе це :)):

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

Зразок вводу є 10 5 0.

Безголівки:

: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))
\\\|||||||

4

JS (ES6) - 79 74 72 65 62

завдяки @nderscore!

3-й парам - булевий (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); // => "\\\\\\\\||"

1
цей запис може бути довідковою карткою для ECMAScript 6: D
bebe

@bebe haha, і це навіть не його остаточна форма. 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]. Повторити (c? B-1: d ) + "| /" [c] .повторити (c? d: b-1)
xem

Я не думаю, що повторне згладжування не варто. [r='repeat'][r]15 символів. .repeat.repeat14 символів
edc65

3

Python2 / 3 - 54

Останнє додане за правилом було досить приємно (0/1 замість 'l' / 'r'). Зроблено шахтою насправді менше, ніж існуючий розчин пітона. 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)) # => \\\\\|||||

3

Хаскелл , 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суміжних символів із початковою позицією, визначеною арифметично.


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 за подальший гольф.


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):''

редагувати: пропустив очевидний символ


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 |||||||||/

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 теж перевернуте.


1
замінити $p--if$dна те, $p-=$dщоб втратити двох символів :)
китайський perl goth

2

Haskell , 57 байт

Завдяки цій підказці збережено 4 байти

f 0 b _=[]
f a b c=last("|/":["\\|"|b>c])!!c:f(a-1)(b-1)c

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

Haskell , 69 61 60 58 байт

(0!b)_=[]
(a!b)c|b==c=a!b$c+1|1>0="\\|/"!!c:((a-1)!(b-1))c

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

Не дуже складна відповідь, але вона обіграє обидві існуючі відповіді Haskell.




1

PHP - 64

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

Простий цикл і лунаючий персонаж.

Генерує Notice: Undefined variable: i, ось ще одна версія silenting помилку (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));}

1

Скала 75 символів

def f(l:Int,p:Int,t:Char)=if(t=='l')"\\"*p++"|"*(l-p) else "|"*(l-p):+"/"*p

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 разів


1

Звичайний Лисп

Це не виграє в коді гольфу, але це підкреслює загальну директиву щодо формату обгрунтування 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.

EDIT: Наступний код робить те саме.

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 '/';
            }
        }
    }
}

Отримали більш детальну версію?
Martijn

1
@Martijn, я змінив свою публікацію, щоб включити її.
TribalC Chief

Тепер я бачу, що це робить. Нічого занадто вигадливого, але +1 :)
Martijn

Спасибі! Рішення @NPlay, хоча, виглядають фантастично!
TribalC Chief

кілька порад щодо гольфу: 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

C ++ 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;}

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 = 'повторити'; d = '|' [l] (- a-b ++); повернути c> 'q'? d + "/" [l] (b): "\\" [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)
||||||////


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.