Официальный рубиновый инспектор

30

Вот простой ASCII арт рубин :

  ___
 /\_/\
/_/ \_\
\ \_/ /
 \/_\/

Как ювелир для ASCII Gemstone Corporation, ваша работа заключается в осмотре недавно приобретенных рубинов и оставлении записки о любых найденных вами дефектах.

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

В 12 дефектов соответствуют замене одного из 12 внутренних _, /или \персонажей рубина с символом пробела ( ). Внешний периметр рубина никогда не имеет дефектов.

Дефекты нумеруются в соответствии с тем, какой внутренний символ имеет место на своем месте:

номера дефектов

Итак, рубин с дефектом 1 выглядит так:

  ___
 /\_/\
/_/  _\
\ \_/ /
 \/_\/

Рубин с дефектом 11 выглядит так:

  ___
 /\_/\
/_/ \_\
\ \_/ /
 \ _\/

Это та же идея для всех других дефектов.

Вызов

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

Возьмите ввод из текстового файла, стандартного ввода или аргумента строковой функции. Верните номер дефекта или распечатайте его на стандартный вывод.

Вы можете предположить, что у рубина есть завершающий символ новой строки. Вы не можете предполагать, что в нем есть завершающие пробелы или начальные символы новой строки.

Самый короткий код в байтах побеждает. ( Удобный счетчик байтов. )

Тестовые случаи

13 точных типов рубинов, за которыми непосредственно следует ожидаемый результат:

  ___
 /\_/\
/_/ \_\
\ \_/ /
 \/_\/
0
  ___
 /\_/\
/_/  _\
\ \_/ /
 \/_\/
1
  ___
 /\ /\
/_/ \_\
\ \_/ /
 \/_\/
2
  ___
 /\_/\
/_  \_\
\ \_/ /
 \/_\/
3
  ___
 /\_/\
/_/ \_\
\  _/ /
 \/_\/
4
  ___
 /\_/\
/_/ \_\
\ \ / /
 \/_\/
5
  ___
 /\_/\
/_/ \_\
\ \_  /
 \/_\/
6
  ___
 /\_/\
/_/ \ \
\ \_/ /
 \/_\/
7
  ___
 /\_ \
/_/ \_\
\ \_/ /
 \/_\/
8
  ___
 / _/\
/_/ \_\
\ \_/ /
 \/_\/
9
  ___
 /\_/\
/ / \_\
\ \_/ /
 \/_\/
10
  ___
 /\_/\
/_/ \_\
\ \_/ /
 \ _\/
11
  ___
 /\_/\
/_/ \_\
\ \_/ /
 \/_ /
12
Кальвин Хобби
источник
Чтобы уточнить, рубин не может иметь пробелы, верно?
Оптимизатор
@ Оптимизатор Исправлен
Хобби Кельвина
@ Calvin'sHobbies May мы также предполагаем , что вход действительно не имеет косой символ новой строки?
Orlp
@ или да Вот и весь смысл мая .
Увлечения Кэлвина
Рубины симметричны. Так не должна ли ошибка № 7 быть такой же, как ошибка № 10, например?
DavidC

Ответы:

13

CJam, 27 23 байта

F7EC5ZV4DI8G6]qBb67%J%#

Конвертируйте базу 11, возьмите мод 67, возьмите мод 19 результата, затем найдите индекс того, что у вас есть в массиве

[15, 7, 14, 12, 5, 3, 0, 4, 13, 18, 8, 16, 6]

Магия!

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

Sp3000
источник
34

Ruby 2.0, 69 байт

#!ruby -Kn0rdigest
p'×ñF<ìX‚ɲŸ_'.index Digest::MD5.digest(gets)[0]

Hexdump (для точного отображения двоичных данных в строке):

00000000  23 21 72 75 62 79 20 2d  4b 6e 30 72 64 69 67 65  |#!ruby -Kn0rdige|
00000010  73 74 0a 70 27 d7 f1 46  3c 1f ec 58 82 c9 b2 9f  |st.p'..F<..X....|
00000020  5f 02 27 2e 69 6e 64 65  78 20 44 69 67 65 73 74  |_.'.index Digest|
00000030  3a 3a 4d 44 35 2e 64 69  67 65 73 74 28 67 65 74  |::MD5.digest(get|
00000040  73 29 5b 30 5d                                    |s)[0]|

Объяснение:

  1. -KnВариант читает исходный файл как ASCII-8BIT(двоичный).
  2. -0Опция позволяет getsчитать весь вход (а не только одну строку).
  3. -rdigestВариант загружает digestмодуль, который обеспечивает Digest::MD5.
  4. Затем код выполняет ввод MD5, берет первый байт дайджеста и получает его индекс в заданной двоичной строке.
Крис Шут-Янг
источник
К счастью, MD5 уникален для самого первого символа
Оптимизатор
15
Никакой удачи не требуется. Каждый байт имеет 256 возможностей, поэтому первый байт, отличающийся для 13 хешей, не так уж необычен. Но если бы они столкнулись по какой-либо причине, я бы просто использовал второй байт хеша.
Крис Джестер-Янг
14
Написать Ruby инспектора в Ruby. Естественно!
Мачта
Следующая задача: проверить этот пост сам
Программы Redwolf
7

Юлия, 90 59 байт

Определенно не самая короткая, но прекрасная девушка Юлия очень внимательно следит за осмотром королевских рубинов.

s->search(s[vec([18 10 16 24 25 26 19 11 9 15 32 34])],' ')

Это создает лямбда-функцию, которая принимает строку sи возвращает соответствующий номер дефекта рубина. Чтобы назвать его, дайте ему имя, например f=s->....

Ungolfed + объяснение:

function f(s)
    # Strings can be indexed like arrays, so we can define d to
    # be a vector of indices corresponding to potential defect
    # locations

    d = vec([18 10 16 24 25 26 19 11 9 15 32 34])

    # Check the specified locations for defects, returning the
    # defect number as the index where a space was found and
    # was not expected. If no spaces are found, 0 is returned.

    search(s[d], ' ')
end

Примеры:

julia> f("  ___
 /\\ /\\
/_/ \\_\\
\\ \\_/ \/
 \\/_\\/")
2

julia> f("  ___
 /\\_/\\
/_/ \\_\\
\\ \\_/ \/
 \\/_\\/")
0

Обратите внимание, что на входе необходимо указывать обратную косую черту. Я подтвердил с @ Calvin'sHobbies, что все в порядке.

Дайте мне знать, если у вас есть какие-либо вопросы или предложения!


Изменить: Сохранено 31 байт с помощью Эндрю Пилизер!

Алекс А.
источник
Вы можете избавиться от цикла for searchи индексации массива. s->(d=reshape([18 10 16 24 25 26 19 11 9 15 32 34],12);search(s[d],' ')), Мне не нравится изменение формы, но я не мог придумать более короткий способ получить массив 1d.
Андрей говорит восстановить Монику
@AndrewPiliser: Спасибо, я очень ценю ваш вклад! Я отредактировал, чтобы использовать ваше предложение. Кроме того, более короткий способ, чем reshape()использовать vec(). :)
Алекс А.
7

> <> (Рыба) , 177 байт

Это долгое, но уникальное решение. Программа не содержит арифметических или ветвлений, кроме вставки входных символов в фиксированные места в коде.

Обратите внимание, что все проверенные символы построения ruby ​​( / \ _) могут быть «зеркалами» в коде> <>, которые изменяют направление указателя инструкции (IP).

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

iiiiiiiii19pi1cpi18piiii2bpi27pii28pi3apiiiii37pi49pi36piiiii00pi45pii46p

    ;
   ;n
  ;nb
 ;n6S    0n;
 n3SB   cn;
 8SB!  4n;
 SB!  1n;
>B! U9n;
 ! U5
  U7n
 Uan;
 2n;
 n;
 ;

Эти S B Uписьма являются те , изменены , чтобы / \ _соответственно. Если вход является полным ruby, окончательный код становится:

\iiiiiiii19pi1cpi18piiii2bpi27pii28pi3apiiiii37pi49pi36piiiii00pi45pii46p

    ;
   ;n
  ;nb
 ;n6/    0n;
 n3/\   cn;
 8/\!  4n;
 /\!  1n;
>\! _9n;
 ! _5
  _7n
 _an;
 2n;
 n;
 ;

Вы можете попробовать программу с этим отличным визуальным переводчиком онлайн . Поскольку вы не можете вводить там новые строки, вы должны использовать вместо этого несколько фиктивных символов, чтобы вы могли ввести полный рубин, например SS___LS/\_/\L/_/S\_\L\S\_/S/LS\/_\/. (Пробелы также изменились на S из-за уценки.)

randomra
источник
5

CJam, 41 31 29 28 байт

"-RI)11a!"q103b1e3%A/c#

Как обычно, для непечатаемых символов перейдите по этой ссылке .

Попробуйте онлайн здесь

Объяснение скоро


Предыдущий подход:

Уверен, это можно уменьшить, изменив логику цифр / преобразования. Но здесь идет первая попытка:

"<KJ[]\"O=":iqN-"/\\_ "4,er4b1e3%A/#

Как обычно, используйте эту ссылку для непечатных символов.

Логика довольно проста

  • "Hash for each defect":i - Это дает мне хэш за дефект в качестве индекса
  • qN-"/\\_ "4,er - это преобразует символы в числа
  • 4b1e3%A/ - это уникальный номер в базовом преобразованном числе
  • # Тогда я просто нахожу индекс уникального числа в хэше

Попробуйте онлайн здесь

оптимизатор
источник
Так близко, я на 1 персонаж ниже тебя!
Orlp
О, у меня уже есть 28. Был слишком занят, чтобы обновить
Оптимизатор
Я думаю, что мой ответ является оптимальным для Pyth. Pyth действительно нужна хеш-функция ( .hсейчас она бесполезна, потому что она использует встроенные ненадежные и плохие функции hash()), до тех пор я не могу добиться большего успеха.
Орл
4

Slip , 123 108 + 3 = 111 байт

^6 (`\\`_.?<?.?[ _]?|`_(`\.?(<.?|>)|`/.?.?>.?.?).?)| `_(`\.?<.?>?.?.?|`/(.?>.?.?.?|<`_))| `/\`_.?(.<.?>?.?)?

Запуск с nи oфлагами, т.е.

py -3 slip.py regex.txt input.txt no

Или попробуйте онлайн .


Slip - это язык, похожий на регулярные выражения, который был создан в рамках задачи сопоставления двухмерных шаблонов . Слип может определять местоположение дефекта с помощью pфлага положения с помощью следующей программы:

^6? `_[/\]|( `/|^6 `\)\`_

который ищет один из следующих шаблонов (здесь Sобозначает, что матч начинается):

S_/    S_\    /_S    \_S    S/      _
                              _      \S

Попробуйте онлайн - координаты выводятся в виде пары (x, y). Все читается как обычное регулярное выражение, за исключением того, что:

  • ` используется для побега,
  • <> поверните указатель совпадения влево / вправо соответственно,
  • ^6 устанавливает указатель совпадения влево и
  • \ сдвигает указатель совпадения ортогонально вправо (например, если указатель направлен вправо, то он идет вниз по строке)

Но, к сожалению, нам нужно одно число от 0 до 12, указывающее, какой дефект был обнаружен, а не где он был обнаружен. У скольжения есть только один метод вывода одного числа - nфлаг, который выводит количество найденных совпадений.

Таким образом, чтобы сделать это, мы расширяем приведенное выше регулярное выражение, чтобы соответствовать правильному числу раз для каждого дефекта, с помощью oперекрывающегося режима соответствия. Разбитые компоненты:

1 11:    `_`\.?<.?>?.?.?
2 10:    `/\`_.?(.<.?>?.?)?
4 9:     `_`/(.?>.?.?.?|<`_)
3 12:   ^6 `_`/.?.?>.?.?.?
5 7:    ^6 `\\`_.?<?.?[ _]?
6 8:    ^6 `_`\.?(<.?|>).?

Да, это чрезмерное использование, ?чтобы получить правильные числа: P

Sp3000
источник
Хаха, потрясающе. Мне нужно добавить больше типов вывода на мой язык.
BMac
4

JavaScript (ES6), 67 72

Просто ищет пробелы в данных 12 местах

Редактировать Сохранено 5 байт, спасибо @apsillers

F=b=>[..."0h9fnopia8evx"].map((v,i)=>b[parseInt(v,34)]>' '?0:d=i)|d

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

x='  ___\n /\\_/\\\n/_/ \\_\\\n\\ \\_/ /\n \\/_\\/' // no defects
;[...x].forEach((c,p,a)=>{
  a[p]=' ' // put a blank
  y=a.join('') // rebuild a string
  d=F(y) // check
  if (d) console.log('\n'+y+'\n'+d) // if defect, output
  a[p]=c // remove the blamk
})

Выход

  ___
 / _/\
/_/ \_\
\ \_/ /
 \/_\/
9

  ___
 /\ /\
/_/ \_\
\ \_/ /
 \/_\/
2

  ___
 /\_ \
/_/ \_\
\ \_/ /
 \/_\/
8

  ___
 /\_/\
/ / \_\
\ \_/ /
 \/_\/
10

  ___
 /\_/\
/_  \_\
\ \_/ /
 \/_\/
3

  ___
 /\_/\
/_/  _\
\ \_/ /
 \/_\/
1

  ___
 /\_/\
/_/ \ \
\ \_/ /
 \/_\/
7

  ___
 /\_/\
/_/ \_\
\  _/ /
 \/_\/
4

  ___
 /\_/\
/_/ \_\
\ \ / /
 \/_\/
5

  ___
 /\_/\
/_/ \_\
\ \_  /
 \/_\/
6

  ___
 /\_/\
/_/ \_\
\ \_/ /
 \ _\/
11

  ___
 /\_/\
/_/ \_\
\ \_/ /
 \/_ /
12
edc65
источник
@apsillers это хорошо и даже лучше, спасибо. Поскольку входная строка всегда начинается с '', начальный 0 вызывает инициализацию d в i в первом цикле, поэтому 'd = 0' можно удалить.
edc65
2

C, 98 84 байта

g(char*b){char*c="/'-5670(&,=?",*a=c;for(;*c&&!(*b=b[*c++-30]-32?0:c-a););return*b;}

ОБНОВЛЕНИЕ: Немного умнее со строкой, и исправлена ​​проблема с неискаженными рубинами.

разгадали:

g(char*b){
    char*c="/'-5670(&,=?",*a=c;
    for(;*c&&!(*b=b[*c++-30]-32?0:c-a);)
        ;
    return*b;
}

Довольно просто и чуть менее 100 байтов.

Для тестирования:

#include "stdio.h"
int main() {
    char b[100];
    scanf("%35c", b);
    printf("%d\n", g(b));
    return 0;
}

Вход в STDIN.

Как это работает

Каждый дефект в рубине находится у другого персонажа. Этот список показывает, где каждый дефект встречается во входной строке:

Defect 1: 17
Defect 2: 9
Defect 3: 15
Defect 4: 23
Defect 5: 24
Defect 6: 25
Defect 7: 18
Defect 8: 10
Defect 9: 8
Defect 10: 14
Defect 11: 31
Defect 12: 33

Поскольку создание массива {17,9,15,23,24,25,18,10,8,14,31,33}стоит много байтов, мы находим более короткий способ создания этого списка. Заметьте, что добавление 30 к каждому числу приводит к списку целых чисел, которые могут быть представлены как печатные символы ASCII. Этот список выглядит следующим образом : "/'-5670(&,=?". Таким образом, мы можем установить массив символов (в коде c) для этой строки и просто вычесть 30 из каждого значения, которое мы извлекаем из этого списка, чтобы получить наш исходный массив целых чисел. Мы определяем, aчтобы быть равным cдля отслеживания того, как далеко по списку мы получили. Единственное, что осталось в коде - это forцикл. Он проверяет, что мы еще не достигли конца c, а затем проверяет, является ли символ bв текущем месте cпробелом (ASCII 32). Если это так, мы устанавливаем первый, неиспользуемый элементb на номер дефекта и вернуть его.

BrainSteel
источник
2

Python 2, 146 88 86 71 байт

Функция fпроверяет местоположение каждого сегмента и возвращает индекс дефектного сегмента. Проверка первого байта входной строки гарантирует, что мы вернемся, 0если дефектов не найдено.

Теперь мы упаковываем смещения сегментов в компактную строку и используем их ord()для восстановления:

f=lambda s:sum(n*(s[ord('ARJPXYZSKIO`b'[n])-65]<'!')for n in range(13))

Тестирование с идеальным рубином:

f('  ___\n /\\_/\\\n/_/ \\_\\\n\\ \\_/ /\n \\/_\\/')
0

Тестирование с заменой сегмента 2 пробелом:

f('  ___\n /\\ /\\\n/_/ \\_\\\n\\ \\_/ /\n \\/_\\/')
2

РЕДАКТИРОВАТЬ: Спасибо @xnor за хорошую sum(n*bool for n in...)технику.

EDIT2: Спасибо @ Sp3000 за дополнительные советы по игре в гольф.

Логика Найт
источник
2
Я думаю, что вы можете сохранить символы с помощью индикатора-суммы sum(n*(s[...]==' ')for ...).
xnor
1
Учитывая, что замененные символы все после пробела, вы можете сделать что-то вроде, <'!'а не ==' 'для байта. Вы также можете создать список с помощью map(ord, ...), но я не уверен, что вы думаете о непечатных :)
Sp3000
1

Pyth, 35 31 28 байт

hx"*6#,54@"C%imCds.zT67

Требуется пропатченный Pyth , в текущей последней версии Pyth есть ошибка, .zкоторая удаляет висячие символы.

Эта версия не использует хеш-функцию, она использует базовую функцию преобразования в Pyth для вычисления очень глупого, но работающего хеша. Затем мы конвертируем этот хэш в символ и ищем его индекс в строке.

Ответ содержит непечатаемые символы, используйте этот код Python3 для точной генерации программы на вашем компьютере:

garbage = [42, 22, 54, 35, 44, 28, 31, 53, 52, 64, 16, 11]
prg = 'hx"' + "".join(chr(c) for c in garbage) +'"C%imCds.zT67'
open("golf_gen.pyth", "w").write(prg)
print(len(prg))
orlp
источник
1

Haskell, 73 байта

f l=last[x|x<-[0..12],l!!([0,17,9,15,23,24,25,18,10,8,14,31,33]!!x)==' ']

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

Ними
источник
0

05AB1E , 16 байтов

•W)Ì3ô;4(•₆вèðk>

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

Объяснение:

W3ô;4(•        # Push compressed integer 2272064612422082397
          ₆в      # Converted to Base-36 as list: [17,9,15,23,24,25,18,10,8,14,31,33]
            è     # Index each into the (implicit) input-string
             ðk   # Get the 0-based index of the first space in the indexed characters
                  # (-1 if not found, which means the ruby had no defects)
               >  # And increase it by 1 (which is output implicitly as result)

Посмотрите этот мой совет 05AB1E (разделы Как сжимать большие целые числа? И Как сжимать целочисленные списки? ), Чтобы понять, почему •W)Ì3ô;4(•есть 2272064612422082397и •W)Ì3ô;4(•₆весть [17,9,15,23,24,25,18,10,8,14,31,33].

Кевин Круйссен
источник