Симулировать вращение доски

14

Вступление

Вы играете в игру на совпадение, в которой монеты вставляются сверху и падают вниз (на верхнюю монету) под действием силы тяжести.

Так это

O <- inserting this coin

OO O
OOOOO

станет этим

O
OO O
OOOOO

Теперь представьте, что кто-то вращает доску по часовой стрелке. Произойдет следующее:

1. Доска вращается

OOO
OO
O
OO
O

2. Монеты падают под действием силы тяжести

O
O
OO
OO
OOO

Твое задание

Ваша задача - смоделировать вращение доски, написав программу или функцию. Для простоты мы имеем дело только с одним видом монет (это не слишком захватывающая игра на совпадение, правда ...). Вы можете предположить, что гравитация применяется только после завершения вращения. Доска вращается по часовой стрелке.

вход

На входе будет строка, которая содержит 3 типа символов:

  • O (заглавная o) ИЛИ 0 (ноль) - монета (вы сами решаете, какую из них поддерживает ваше решение)
  • (пробел) - пустое поле
  • \ n (новая строка) - конец строки

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

Выход

На выходе появляется новое состояние платы после вращения. Вывод содержит те же 3 типа символов, что и ввод. Вывод может быть возвращен из вашей функции или может быть записан в стандартный вывод или в файл.

Образец

Input1:

O
OO O
OOOOO

Output1:

O
O
OO
OO
OOO

Input2:

O O
O O

Выход2:

OO
OO

Вы можете использовать любой язык и стандартную библиотеку выбранного языка. Самая короткая программа в байтах побеждает.

Дэвид Франк
источник
Короткие линии дополняются пробелами?
Вентеро
Если вам так нужно, тогда да.
Дэвид Фрэнк
Каковы требования к размеру платы? Могу ли я выбрать разумный максимальный размер или приложение / функция должны работать для всех возможных размеров?
Форс
2
Если гравитация применяется после вращения, как Вход2 становится Выходом2? Я думал бы, что это опустит верхние монеты вниз, но не горизонтально?
Мэтт
2
@Matt Обратите внимание, что ни в Input2, ни в Output2 нет пустых строк (SE отображает поле между строками).
Дэвид Франк

Ответы:

16

GolfScript, 14 12 символов

' '-n%zip$n*

Ввод необходимо указать в STDIN, символ для монет может быть любым непробельным символом. Попробуй здесь . Спасибо Питеру за указание на сокращение двух символов.

Говард
источник
О, что бы я не дал transposeв Ruby, который может обрабатывать массивы различной длины ...
Ventero
@Ventero Большую часть времени я использую эту Hacky версию: ([nil]*a.map(&:size).max).zip(*a). Не хорошо для игры в гольф, хотя.
Говард
Вы можете сохранить 2 символа: поскольку самые длинные строки всегда заканчиваются снизу, вы можете заменить их -1%на $.
Питер Тейлор
@PeterTaylor Вы правы - мы можем сохранить в символах. Спасибо.
Говард
1
@PeterTaylor Ну, я включил односимвольный псевдоним для " ".
Aditsu уйти, потому что SE зла
6

Javascript (E6) 103

Сначала попробуйте просто матричные операции. Каждая строка во входной строке должна быть дополнена.
Довольно многословно.

R=t=>(x=t.split('\n').reverse().map(x=>[...x].sort()),x.map((c,i)=>x.map(r=>r[i]).join('')).join('\n'))

Псевдокод

  1. строка -> массив строк
  2. обратный массив вверх / вниз
  3. каждая строка -> массив символов
  4. сортировать каждый ряд (монеты «падают» вправо)
  5. транспонирования
  6. каждый массив символов в строке -> строка
  7. объединить массив -> одна строка
edc65
источник
Ух ты, сортировка умная (+1)! Не возражаешь, если я украду это?
seequ
Я никогда не видел синтаксис [...x]раньше. Как это называется?
ComFreek,
2
@ComFreak это называется spread[ developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
edc65
2
@ edc65 Вы сломали собственную ссылку в скобках. Вот правильная ссылка
Крис Cirefice
6

Ruby 2.0, 59 символов

puts$<.map(&:chars).reverse.transpose.sort[1,50].map &:join

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

Ventero
источник
Я думаю, что вы можете использовать $<.mapвместо этого.
Говард
@ Говард Это одна вещь, которую я всегда забываю. Благодарность!
Вентеро
1
что [1,50] там делает?
Не то чтобы Чарльз
1
@Charles Пропускает первую строку, которая содержит все новые строки из ввода. Дэвид упомянул в комментарии, что 50x50 - максимально возможный размер, поэтому вместо выбора всех, кроме первой строки ( 1..-1), я просто выбираю 50 строк, начиная со второй ( 1,50).
Вентеро
@ Ventero получил это. круто. Благодарность!
Не то чтобы Чарльз
3

J - 49 31 24 байта

Я думаю, что там могут быть ненужные повороты, но в противном случае он работает нормально. Это функция, которая принимает входные данные, как указано, монеты O. Конечный пробел не требуется при вводе.

Новая версия, вдохновленная Javascript-ответом edc65 :

f=:[:|."1@|:[:/:~"1,;._2

Объяснение:

f=:[:|."1@|:[:/:~"1,;._2
                   ,;._2 Split the string at every fret, which is the last character in the string (newline).
              /:~"1      Sort every row separately.
     |."1@|:             Rotate the array clockwise.

Старая версия:

f=:[:|:((#~=&' '),=&'O'#])"1@|:@(|."1@|:)@(,;._2)

Объяснение:

f=:[:|:((#~=&' '),=&'O'#])"1@|:@(|."1@|:)@(,;._2)
                                          (,;._2) Split the string at every fret, which is the last character in the string (newline).
                                (|."1@|:)@        Rotate the array clockwise.
                             |:@                  Reverse the axes (columns become rows and vice-versa).
       ((#~=&' '),=&'O'#])"1                      Function that applies the "gravity"
                          "1                       Apply to every row separately:
                  =&'O'#]                           Get the O's in the row.
       (#~=&' ')                                    Get the spaces in the row.
                ,                                   Join them, spaces come first.
  [:|:                                            Reverse axes again.

Примеры (обратите внимание, что многострочные строки начинаются 0 : 0и заканчиваются скобкой):

   f 0 : 0
O
OO O
OOOOO
) NB. output starts now
O  
O  
OO 
OO 
OOO
   f 0 : 0
O O
O O
) NB. Output starts now.

OO
OO
seequ
источник
Если можете,
сортируйте
@ edc65 Ты умный человек.
seequ
2

Хаскель - 86

Просто учусь, поэтому я уверен, что это можно улучшить.

import Data.List
c=putStr.unlines.filter(/="").sort.map(filter(/=' ')).transpose.lines

Пример ввода:

let a = "O    \nOO O \nOOOOO"
let b = " O O \n O O "
c a
c b

Пример вывода:

O
O
OO
OO
OOO

OO
OO
О.И.
источник
2

Питон 2 (69) (79)

for c in sorted(zip(*raw_input().split("\\n"))):print''.join(c[::-1])

Принимает ввод, дополненный пробелами, поэтому все строки имеют одинаковую длину. splitСоздает arrat каждой строки. zipЭффективно переставляет массив. Затем sortedсортирует кортежи в лексикографическом порядке, в результате чего все монеты падают на дно. Наконец, мы печатаем каждую строку, превращая ее обратно в строку, хотя сначала мы должны обратить ее. Выполнение print'O'*c.count('O')эквивалентно и использует одинаковое количество символов.

Пример выполнения:

>> O    \nOO O \nOOOOO
O
O
OO
OO
OOO
XNOR
источник
1

C 167 119 байт

Эта более короткая версия (к сожалению?) Намного яснее, чем оригинал.

m;j;b[99];r;main(){while(j=getchar()+1)j-11?m+=j-33&&++b[r]>m:++r;for(j=r;m+1;putchar(j--?m<b[j]?79:32:(j=r,m--,10)));}
j_random_hacker
источник
0

Ракетка: 130

(let l((a'()))(let((b(sort(string->list(read-line))char<?)))(if
(null? b)(apply map(λ x(map display x)(newline))a)(l(cons b a)))))

Это требует, чтобы вы дополняли пробелами, чтобы линии были равны по длине.

Сильвестер
источник
0

C # - 209 174 байта

Правильно, я должен попробовать этот Кодекс гольф в какой-то момент, который я считаю. Создана функция (r), которая вращает доску и печатает ее. Я предполагаю, что немного обманываю, когда печатаю свой массив символов, но если вы не можете понять, почему вы не должны злиться :)

Спасибо ProgramFOX за советы :)

void r(string s){int x=s.IndexOf('\n'),j,i=-1,k,z=x+1;var y=new char[x*x+x];for(;++i<x;y[z*(i+1)-1]='\n')for(k=j=x;j>0;)if(s[i*z+--j]=='0')y[k--*z-i-2]='0';Console.Write(y);}

Чит

new char[x*x+x]заполняет массив, '\0'а не' '

WozzeC
источник
1
Удаление новых строк и удаление пробела между char[]и yуменьшит количество ваших персонажей до 192 символов. Кроме того, нет необходимости указывать ключевое слово staticпри размещении ответа здесь. Удаление его уменьшит количество ваших персонажей до 185 символов.
ProgramFOX
Я также смог удалить 'ref', который был забыт с предыдущей попытки.
WozzeC