Wpisz wszystkie możliwe znaki brajlowskie

13

Ciekawa łamigłówka przyszła mi dziś rano, patrząc na przyciski windy.

Musisz wygenerować listę wszystkich wzorów brajlowskich pasujących do siatki 2x3. Użyj skrótu, #aby oznaczyć wypukłość, a łącznika, -aby oznaczyć płaski obszar.

Oczekiwana próbka wyjściowa:

#-
--
--

##
--
--

#-
#-
--

(and so on...)

Zasady:

  • Twój program musi oddzielić każdy wzór co najmniej jednym znakiem lub linią.
  • Wzory mogą być generowane w dowolnej kolejności.
  • Wszystkie wzory, niezależnie od tego, czego faktycznie używa alfabet Braille'a, powinny zostać wyprodukowane. Całkowicie pusty wzór jest opcjonalny.
  • Należy generować tylko unikalne wzorce wypukłości. Następujące wzory są uważane za równoważne, ponieważ guzy mają identyczny układ. W takich przypadkach użyj wzoru znajdującego się najbliżej lewego górnego rogu (tj. Pierwszej opcji w tym przykładzie).
#-  -#  --  --
#-  -#  #-  -#
--  --  #-  -#

Dodatkowe punkty, jeśli można zrobić to praca dla każdego x przez y wielkości siatki. ( EDYCJA: W rozsądnych granicach. Do potwierdzenia koncepcji wystarcza 4x4).

Po przeczytaniu artykułu na wiki okazuje się, że jest 45 wzorów (w tym pustych), które spełniają zasady tej układanki.

Hand-E-Food
źródło
Nie do końca się liczy, ale jest bardzo blisko. Dla siatek xx ygenerujesz pierwsze 2^(xy)liczby i odfiltrowujesz te, które maskują do 0 przed 2^x - 1lub (2^(xy+1) - 1)/(2^y - 1).
Peter Taylor

Odpowiedzi:

6

GolfScript, 34 32 znaki

44,{84+2base(;{'-#'=}/@\n.}%2/n*

Okazuje się, że nie krótsze niż tylko generowanie rozwiązania wszystkich 64 wzorów i odfiltrowanie tych złych. W rzeczywistości, poprzez odpowiednie mapowanie bitów na pozycje siatki, możliwe jest mapowanie wszystkich prawidłowych (niepustych) wzorów na kolejny zakres liczb, tak jak robi to ten program.

W szczególności używam mapowania:

5 4
3 1
2 0

gdzie liczby oznaczają pozycję bitu (zaczynając od najmniej znaczącego bitu 0) zmapowaną do tej pozycji w siatce. Przy takim mapowaniu prawidłowe siatki odpowiadają liczbom od 20 do 63 włącznie.

Jest to prawie to samo, co oczywiste mapowanie uzyskane przez zapisanie 6-bitowej liczby w systemie binarnym i dodanie przerw między wierszami między co drugim bitem, z wyjątkiem tego, że bity 1i 2są zamieniane - i tak właśnie oblicza to mój program. (Dodaję również 64 do liczb przed konwersją ich na binarne, a następnie usuwam bardzo wysoki bit; to po prostu zerowanie liczb do 6 bitów, ponieważ w baseprzeciwnym razie GolfScript nie zwróciłby żadnych zer wiodących.)

Ps. Demo online tutaj. (Serwer wydaje się ostatnio przeciążony; jeśli masz limit czasu, spróbuj ponownie lub pobierz interpreter i przetestuj go lokalnie).

Edycja: Udało się zaoszczędzić dwa znaki, unikając niepotrzebnego budowania i zrzutu tablicy. Uff!

Ilmari Karonen
źródło
2
Czy masz coś przeciwko dodaniu kilku szczegółów? Chcę zobaczyć, jak definiujesz to mapowanie.
nowy
@ardnew: Gotowe, patrz wyżej.
Ilmari Karonen
Myślę, że to zmieni wiele odpowiedzi ludzi. :-)
Hand-E-Food
3

Mathematica 97

Grid /@ Cases[(#~Partition~2 & /@ Tuples[{"#", "-"}, 6]), x_ /; 
         x[[All, 1]] != {"-", "-", "-"} && x[[1]] != {"-", "-"}]

brajl


Puste nie jest wliczone:

Length[%]

44

NB! = To pojedynczy znak w Mathematica.

DavidC
źródło
3

C # - 205

class C{static void Main(){var s="---##-##";Action<int,int>W=(i,m)=>{Console.WriteLine(s.Substring((i>>m&3)*2,2));};for(int i=0;i<64;++i){if((i&3)>0&&(i&42)>0){W(i,0);W(i,2);W(i,4);Console.WriteLine();}}}}

Wersja do odczytu:

class C
{
    static void Main()
    {
        var s = "---##-##"; // all two-bit combinations
        // a function to write one two-bit pattern (one line of a Braille character)
        Action<int,int> W = (i,m) => { Console.WriteLine(s.Substring(((i >> m) & 3) * 2, 2)); };
        // for all possible 6-bit combinations (all possible Braille characters)
        for(int i = 0; i < 64; ++i)
        {
            // filter out forbidden (non-unique) characters
            if ((i & 3) > 0 && (i & 42) > 0)
            {
                // write three rows of the Braille character and an empty line
                W(i,0);
                W(i,2);
                W(i,4);
                Console.WriteLine();
            }
        }
    }
}
Mormegil
źródło
3

Perl, 71 67 65 char

y/10/#-/,s/../$&
/g,/^#/m&&print
for map{sprintf"%06b
",$_}18..63

Konwertuj int na binarne, wykonuj transliterację i dodawaj nowy wiersz po każdych dwóch znakach. /^#/mTestu eliminuje dwa wzory (20 i 21), które nie mają podniesioną gulę w skrajnej lewej kolumnie.

Ogólne rozwiązanie, 150 106 103 100 char

Czytaj xi yz argumentów wiersza poleceń. Nowe linie są znaczące

y/01/-#/,s/.{$x}/$&
/g,/^#/m*/^.*#/&&print
for map{sprintf"%0*b
",$x*$y,$_-1}1..1<<($y=pop)*($x=pop)

Iteruj ponad 0..2 xy jak poprzednio, konwertując każdą int na binarną, podstawiając -i #dla 0i 1oraz wstawiając nowy wiersz po każdym $xznaku.

/^#/msprawdza, czy w lewej kolumnie znajduje się wypukły guz, i /^.*#/czy w górnym rzędzie jest wypukły guz. Drukowane są tylko wzory, które przejdą oba testy.

tłum
źródło
Jak to konto uwzględnia nieprawidłowe kombinacje?
scleaver
Ponieważ pętla wyklucza wzorce dla 1..17, 20 i 21.
mob
2

Pyton, 120 118 113 95 118

for j in range(256):
    if j/4&48and j/4&42:print''.join('_#'[int(c)]for c in bin(j/4)[2:].rjust(6,'0'))[j%4*2:j%4*2+2]

Edycja: wykorzystano sugestię Winstona Ewerta i dodano rozwiązanie siatki x by y

Edycja: Jakoś przegapiłem ostatnie ograniczenie dotyczące wyjątkowości. Ten skrypt generuje wszystkie możliwe sekwencje, nie tylko 45.

Edycja: kopia zapasowa do 118, ale teraz poprawna

scleaver
źródło
Wymienić ['#','-']z'#-'
Winston Ewert
2

J, 35 33 znaków

3 2$"1'-#'{~(2 A.i.6){"1#:20+i.44

Wykorzystuje podejście, które wymyślił Ilmari Karonen w swoim rozwiązaniu Golfscript. Ponieważ jednak czasownik J #:(antiase) przechowuje bity (lub, no cóż, cyfry w ogólnym przypadku) na liście, musimy zindeksować je od lewej zamiast od prawej (tzn. Indeks 0 jest skrajnie lewy, najwyższy bit).

Rozwiązanie jest dość proste: 20+i.44podaje listę liczb 20..63, włącznie. #:pobiera antiase-2 każdego elementu z tej listy, a tym samym tworzy listę wzorów bitów dla każdej liczby w tym zakresie. {wybiera (zasadniczo zmienia kolejność) bitów na odpowiedni wzorzec, a następnie {jest ponownie używany, aby użyć cyfr jako wskaźników w ciągu „- #” w celu przygotowania wyniku. Na koniec umieszczamy każde wejście w prostokącie 2 na 3 o $(kształcie).


3 2$"1'-#'{~(2 A.i.6){"1#:20+i.44      N.B. use A. (anagram) to generate the right permutation

3 2$"1'-#'{~0 1 2 4 3 5{"1#:20+i.44

Robaczek świętojański
źródło
Czy ktoś wie, jak (0 2 3 ,. 1 4 5) { #: 44można ulepszyć coś podobnego do pracy z listą liczb, a nie z pojedynczą liczbą? Prawdopodobnie ogoliłbym jeszcze kilka znaków.
FireFly,
1

Python - 121 112

puste miejsce nie jest wliczone

from itertools import*
print'\n'.join('%s%s\n'*3%b for(b,n)in zip(product(*['_#']*6),range(64))if n&48and n&42)
quasimodo
źródło
możesz przyciąć ten produkt za pomocą '_#',repeat=6->*['_#']*6
kabiny
@boothby: dzięki. Ponadto bjest już krotką, więc nie trzeba jej konwertować :)
quasimodo