Прочитайте ретро-дисплей


22

Мистецтво, викрадене з Якого розміру є цифра?


7-сегментні цифри можуть бути представлені в ASCII за допомогою _|символів. Ось цифри 0-9:

 _     _  _       _   _  _   _   _ 
| | |  _| _| |_| |_  |_   | |_| |_|
|_| | |_  _|   |  _| |_|  | |_|  _|

Ваше завдання - розібрати мистецтво на звичайні числа.

Примітки до цифр

  • Кожна цифра має різну ширину.
    • 1 має ширину 1
    • 3і 7в 2ширину
    • 245689і 0всі вони 3широкі

Також між кожною цифрою є одна табличка набивання. Ось повний набір символів:

 // <- має бути один пробіл, але форматування SE переплутало його
|
|
-------------
 _ 
 _ |
| _ 
-------------
_ 
_ |
_ |
-------------

| _ |
  |
-------------
 _ 
| _ 
 _ |
-------------
 _ 
| _ 
| _ |
-------------
_ 
 |
 |
-------------
 _ 
| _ |
| _ |
-------------
 _ 
| _ |
 _ |
-------------
 _ 
| |
| _ |

Вхідні дані

Введення може бути як з консолі, так і як рядковий аргумент функції.

Вихідні дані

Виведення або кладеться на консоль, або повертається з функції.

Приклади:

  _  _   _ 
|  |  | |_ 
|  |  | |_|
1776

 _   _     _ 
 _| | | | |_ 
|_  |_| | |_|
2016

   _       _ 
| |_| |_| |_ 
|  _|   |  _|
1945

   _   _   _   _   _   _ 
| | | | | | | | | | | | |
| |_| |_| |_| |_| |_| |_|
1000000

 _     _  _       _   _  _   _   _ 
| | |  _| _| |_| |_  |_   | |_| |_|
|_| | |_  _|   |  _| |_|  | |_|  _|
0123456789

Це кодовий гольф, тому найкоротший виграш байтових перемог!



Мені цікаво дізнатися про найкращі алгоритми для вирішення подібної проблеми, і мені важко вчитися з відповідей тут (вони хороші, просто дуже стислі). Чи є місце, де ви можете звернутися до мене, щоб побачити більш тривалі пояснення, бажано з фотографіями?

Що ж, спосіб роботи шахти досить простий. Він переміщує список і цикліть його. Потім він розпадається на порожні рядки. Кожне число перевіряється у таблиці з відбитками пальців для кожного номера. Інші працюють трохи, як у мене, за винятком таблиці з відбитками пальців, в основному вони мають хеш-таблицю, яку вони використовують.
J Atkin

Чи існує більш загальна назва цього типу проблем в інформатиці?

Я поняття не маю;)
J Atkin

Відповіді:


4

Pyth, 33 30 байт

sm@."/9Àøw"%%Csd409hTcC.z*3d

Ось ідея: Після того, як ми перенесемо вхід і розділимо їх на цифри, ми зможемо сортувати хеш окремих строків цифр і присвоїти їм їх значення.

sm@."/9Àøw"%%Csd409hTcC.z*3d     Implicit: z=input
                      C.z        Transpose input.
                     c   *3d     Split that on "   ", a space between digits.
 m@."/9Àøw"%%Csd409hT            Map the following lambda d over that. d is a digit string.
             Csd                   Flatten the digit string, and convert from base 256.
            %   409                Modulo that by 409
           %       hT              and then by 11. All digits go to a distinct num mod 11.
   ."/9Àøw"                        The compressed string "03924785/61".
  @                                Index into that string.
s                                Flatten and implicitly output.

Спробуйте тут .


Класно, в основному виглядає як мій підхід, але набагато коротше!
Лінн

@Lynn Вибачте за це; є в основному один найкоротший спосіб зробити це в Pyth.
lirtosiast

4

Рубін, 184 байти

a=0
l=$<.map{|x|x.bytes.map{|y|y==32?0:1}+[0]*2}
(0..l[0].count-1).map{|i|l[0][i]+2*l[1][i]+4*l[2][i]}.each{|x|
x>0?(a=x+2*a):(p Hash[[40,6,32,20,18,26,42,8,44,64].zip(0..9)][a];a=0)}

Пояснення

  • приймає вхід з stdin
  • перетворює рядки у двійкові послідовності, 1/0 для включення / вимикання сегмента
  • кодує стовпці до 3-бітного двійкового числа
  • кодує послідовності з 3-х розрядних чисел до 9-бітних чисел, використовуйте стовпці "0" як символи зупинки
  • використовуйте таблицю пошуку для перетворення 9-бітних чисел у цифри

Це мій перший код-гольф. Дякуємо за задоволення!


2
Ласкаво просимо до PPCG! Дуже приємна робота на вашій першій посаді!
J Atkin


2

Japt, 119 байт

Ur"[|_]"1 z r" +
"R x1 qR² £"11
1 1
1151151
111
 15111
115 1
 1
115 1
111
1511
111
15  1
11511
111
115 1
111
11"q5 bXÃq

Try it here!

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

Пояснення

Підготовка

Ми беремо вхід і перетворюємо будь- |_який 1. Потім переносимо, викреслюємо кінцеві пробіли і розділяємо по подвійним новим рядкам.

Переклад

Ми відображаємо відображається масив і знаходимо індекс, де форма з’являється у довідковому масиві. Ось схема, яка допоможе:

MAPITEM
  11
  1 1 --> This same form appears at index 0 in the reference array
  11                            |
                                |
                                V
                        change the mapitem to 0!

Після цього ми приєднуємося до масиву чисел і виводимо!

ПРИМІТКА : Вам може бути цікаво, чому ми мусимо змінювати кожного художнього персонажа на серію 1-х. Це тому, що, здається, є помилка (чи щось подібне), що не дозволяє мені зберігати символів як зараз |_.


Я помітив _помилку, але не знаю, що це спричинило.
ETHproductions

Гаразд, "\n\n"можна замінити і на , і "\\||_"на "%||_". Я думаю , ви можете також зберегти деякі байти , що кодують довгий рядок в базі 4 (зміна кожного з 4 disinctive символів на 0, 1, 2, або 3, набивка на довжину кратну 4, то працює r"...."_n4 d}над цим), але з якоїсь - то причини , Я ще не змусив цього працювати.
ETHproductions

2

Python2, 299 261 244 байт

s=lambda a,i=0:[a]if i==len(a[0])else[[j[:i]for j in a]]+s([j[i+1:]for j in a])if all(j[i]==' 'for j in a)else s(a,i=i+1)
p=lambda l:['95572431508448853268'.find(`sum(ord(c)**i for i,c in enumerate("".join(n)))%108`)/2for n in s(l.split('\n'))]

Мені дуже сподобався цей виклик, хороша робота!

Пояснення

Функція sприймає три лінії як вхідні дані, вона намагається знайти розряд цифри (усі символи - пробіли). Коли такий поділ знайдено, він дзвонить sрешті трьох рядків і додає значення, повернене викликом, до трьох рядків, що складають цифру. Якщо немає поділу, це означає, що є лише одна цифра.

Функція pє точкою входу, тому вона займає рядок, який представляє цифри. Цифри зберігаються як "хеш", обчислений sum(ord(c)**i for i,c in enumerate("".join(n)))%108для економії місця (завдяки іншим відповідям!).

Приклад

digits="""
 _     _ 
| | |  _|
|_| | |_ """[1:]  # remove the '\n' at the beginning

p(digits)  # [0, 1, 2]

Інші версії

261 байт (py3):

s=lambda a,i=0:[a]if i==len(a[0])else[[j[:i]for j in a]]+s([j[i+1:]for j in a])if all(j[i]==' 'for j in a)else s(a,i=i+1)
def p(l):[print([91,21,84,31,58,76,88,41,80,68].index(sum(ord(c)**i%20 for i,c in enumerate("".join(n)))),end="")for n in s(l.split('\n'))]

249 байт, цей транспонірує рядки (py2):

f="".join
s=lambda a,i=0:[a]if i==len(a)else[a[:i]]+s(a[i+1:])if all(c==' 'for c in a[i])else s(a,i=i+1)
h=lambda s:ord(s[0])**len(s)+h(s[1:])if s else 0
p=lambda l:["10220907112527153129".index(`h(f(map(f,n)))%34`)/2for n in s(zip(*l.split('\n')))]

2

JavaScript (ES6), 169 байт

a=>[...(a=a.split`
`)[0]].map((b,c)=>(d={' ':0,'|':1,'_':2})[b]+d[a[1][c]]*2+d[a[2][c]]).join``.split(0).map(b=>[343,3,182,83,243,281,381,23,383,283].indexOf(+b)).join``

Починається з розбиття на три рядки, перестановки кожного стовпця у значення, а потім побудови унікальної ідентичності для кожного стовпця з цих значень. Потім він розбивається на 0(ідентичність пробілу між стовпцями) і, нарешті, відображає кожну ідентичність на її числові значення, які вона об'єднує та виводить.


Дуже хороша! Я б хотів, щоб пітон мав функцію розбиття списку ...
J Atkin

@JAtkin Я joinстворив рядок, щоб я міг розділити його. Я вважаю, ви могли це зробити і в Python?
Mwr247

0

Python 3, 281 254 байт

Редагувати

Я просто переглянув код для іншої відповіді python і помітив, що значна частина коду схожа. Це було досягнуто самостійно.

(для "читабельності" додані нові рядки)

def p(i):
 n=[[]]
 for l in zip(*i.split('\n')):
  if all(i==" "for i in l):n+=[[]]
  else:n[-1]+=l
 return''.join(map(lambda l:str([''.join(l[2:])==x for x in
             "|_ _ ||,|,|___ | ,_ ||,  _  ||, ___  |,|___  |,  ||,|___ ||, ___ ||"
                     .split(',')].index(1)),n))

Безголівки:

def parse(input):
    lines = list(input.split('\n'))
    numbers = [[]]
    for lst in zip(*lines):
        if all(i==" " for i in lst):
            numbers += [[]]
        else:
            numbers[-1] += lst
    return ''.join(map(digit, numbers))

def digit(num):
    fingerprint = 
        "|_ _ ||,|,|___ | ,_ ||,  _  ||, ___  |,|___  |,  ||,|___ ||, ___ ||".split(',')
    return str([''.join(num[2:]) == y for y in fingerprint].index(True))

Тести:

assert (parse("   _   _   _   _   _   _ \n| | | | | | | | | | | | |\n| |_| |_| |_| |_| |_| |_|") == '1000000')
assert (parse("   _       _ \n| |_| |_| |_ \n|  _|   |  _|") == '1945')
assert (parse(" _   _     _ \n _| | | | |_ \n|_  |_| | |_|") == '2016')
assert (parse(" _     _  _       _   _  _   _   _ \n| | |  _| _| |_| |_  |_   | |_| |_|\n|_| | |_  _|   |  _| |_|  | |_|  _|") == '0123456789')
assert (parse("  _  _   _ \n|  |  | |_ \n|  |  | |_|") == '1776')

Як це працює

(Примітка. Я пояснюю тут непрограшну програму, оскільки вона є більш читаною і має точно такий же код, за винятком того, що digitфункція вбудована в лямбда)

def parse(input):
    lines = list(input.split('\n'))
    numbers = [[]]

Основна функція - parse. Він спочатку розбиває введення на рядки та створює numbersмасив.

    for lst in zip(*lines):
        if all(i==" " for i in lst):
            numbers += [[]]
        else:
            numbers[-1] += lst

Це моя улюблена частина (оскільки це знадобилось стільки часу, щоб розібратися). Ось ми zipлінії, щоб ми могли в основному вертикально пройти вхід. Коли у рядку є символи, ми додаємо його до останнього числа в numbersмасиві. Якщо в ньому немає символів, ми додаємо нове число до масиву.

    return ''.join(map(digit, numbers))

Дійсно простий, numbersвідображається з digitфункцією і перетворюється на рядок.

def digit(num):
    fingerprint = 
        "|_ _ ||,|,|___ | ,_ ||,  _  ||, ___  |,|___  |,  ||,|___ ||, ___ ||".split(',')
    return str([''.join(x[2:]) == y for x, y in zip([num]*10, fingerprint)].index(True))

Це (досить) просто. fingerprint- це рядкове представлення цифр, створених вище мінус перші два знаки (це був найменший відбиток пальця, який я міг знайти). Повертаємо індекс першого матчу.


0

Haskell, 270 207 байт

Не будьте занадто важким, це моя перша програма, що коли-небудь має haskell;) Я майже впевнений, що це можна пограти в гольф далі, але я не знаю, як дано моє обмежене знання мови.

import Data.Lists
b n=map c$splitOn["   "]$transpose$lines n
c n|e<-drop 2$concat n,Just r<-elemIndex True[e==f|f<-splitOn",""|_ _ ||,|,|___ | ,_ ||,  _  ||, ___  |,|___  |,  ||,|___ ||, ___ ||"]=(show r)!!0

Безголівки:

module Main where
import Data.Lists

main :: IO ()
main = print $ parse " _     _  _       _   _  _   _   _ \n| | |  _| _| |_| |_  |_   | |_| |_|\n|_| | |_  _|   |  _| |_|  | |_|  _|"

parse :: String -> String
parse n = let lst = transpose $ lines n
              numbers = splitOn ["   "] lst --"   " lst
              number = map digit numbers
          in number

digit :: [String] -> Char
digit n | e <- drop 2 $ intercalate "" n
        , fingerprint <- ["|_ _ ||","|","|___ | ","_ ||","  _  ||"," ___  |","|___  |","  ||","|___ ||"," ___ ||"]
        , Just res <- elemIndex True [e == finger | finger <- fingerprint]
        = head $ show res

Велика подяка @nimi за поради!


По-перше, погані новини: Боюсь, вам доведеться включити import Data.Listсвій рахунок до числа байтів. Хороші новини: а) якщо ви Data.Listsвстановили , ви можете імпортувати його замість цього і замінити aз splitOn: ...map c$splitOn[" "]$transpose...і ...f<-splitOn",""|_.... б) intercalate "" nє concat nабо id=<<n. в) замінити resна одну буквене ім’я. г) використання моделі охоронці замість того , щоб let ... in: c n|e<-drop 2$id=<<n,Just r<-elemIndex ... ]=(show r)!!0.
німі

Hehehe, Whoops! Імпорт був втрачений у копії / вставці;) Дякую за всі поради!
J Atkin

@nimi Вибачте, що вас турбує з цього приводу, але ви не проти пояснити, що =<<робить? Ні документи Google, ні підпис типу мені не дуже корисні.
J Atkin

=<<у контексті списку є concatMap, тобто він відображає задану функцію над списком і об'єднує результати в єдиний список. >>=робить те ж саме, але з аргументами, перевернутими. id =<< n(або n >>= id) відображає функцію ідентичності над списком (списками), тобто нічого не робить із підлістами та з'єднує їх. Так це те саме, що concat.
німі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.