Pokonywanie rozmiaru klastra


37

Mając dość niezawodności pamięci flash, zdecydowałeś się przechowywać wszystkie swoje programy na jednej ze starych dobrych dyskietek 1440 KiB. Jednak po skopiowaniu nawet 3000 programów dysk był pełny. Jak to w ogóle możliwe? Doświadczony w kodzie golfowym, jak jesteś, większość programów nie ma nawet 100 bajtów długości, więc powinno pozostać dużo miejsca ...

Po zapytaniu o to superużytkownika odkrywasz, że zostałeś skrzywdzony przez rozmiar klastra systemu plików , złą fabułę projektantów FAT12, która pozostawia znaczną część twojej dyskietki nieużywaną i zmusza cię do zakupu więcej, niż faktycznie potrzebujesz.

Kup więcej dyskietek? Nigdy! Rozmiar klastra będzie mniejszy, jeśli po prostu zapiszemy wiele programów w jednym pliku, co jest możliwe, ponieważ różne kompilatory / interpretery będą zachowywać się inaczej dla tego samego kodu źródłowego.

Zadanie

Napisz poliglotę, która mieści się w jednym klastrze (512 bajtów lub mniej) i rozwiązuje jak najwięcej z poniższych zadań.

  1. Przeczytaj wszystkie dane wejściowe i wydrukuj je.

  2. Drukuj Witaj, świecie! .

  3. Przeczytaj wiersz / argument ( nazwę ) jako dane wejściowe i wydrukuj Happy Birthday, [nazwa]! .

  4. Przeczytaj wszystkie dane wejściowe i wydrukuj Uwielbiam zakładki! jeśli zawiera jeden lub więcej tabulatorów (0x09) i nienawidzę spacji! jeśli nie.

  5. Przeczytaj dwa wiersze / argumenty i wypisz prawdziwą wartość, jeśli druga jest podciągiem pierwszej, a fałszem, jeśli nie.

  6. Przeczytaj wiersz / argument i wypisz prawdziwą wartość, jeśli jej znaki są w kolejności rosnącej, a jeśli nie, to wartość fałsz.

  7. Przeczytaj wiersz / argument i znak i wydrukuj indeksy wszystkich wystąpień tego znaku.

  8. Przeczytaj wiersz / argument i wydrukuj dowolny ze znaków o największej liczbie wystąpień.

  1. Przeczytaj dwie liczby całkowite od 0 do 255 i wydrukuj ich sumę.

  2. Przeczytaj jedną liczbę całkowitą od 0 do 255 i wydrukuj iloraz i resztę jego dzielenia przez 7 .

  3. Odczytaj jedną liczbę całkowitą z przedziału od 1 do 255 i wydrukuj prawdziwą wartość, jeśli jest to liczba złożona (ani 1, ani liczba pierwsza) i wartość fałsz, jeśli nie.

  4. Przeczytaj jedną liczbę całkowitą z przedziału od 1 do 255 i wydrukuj prawdziwą wartość, jeśli jest to potęga 2, a wartość fałsz, jeśli nie.

  5. Przeczytaj dwie liczby całkowite od 0 do 255 i wydrukuj większą.

  6. Przeczytaj dziesiętną liczbę całkowitą od 0 do 255, wypisz jej reprezentację szesnastkową.

  7. Odczytaj jedną liczbę całkowitą od 0 do 255 i wydrukuj jej wagę Hamminga (liczba 1-bitów).

  8. Przeczytaj jedną liczbę całkowitą n między 1 a 13 i wydrukuj F n , n- liczbę Fibonacciego .

    Na przykład dla danych wejściowych 13wydrukuj 233.

  1. Przeczytaj wiersz / argument wejścia i umieść go w ramce.

    Na przykład dla danych wejściowych Programming Puzzles & Code Golfwydrukuj to:

    +---------------------------------+
    | Programming Puzzles & Code Golf |
    +---------------------------------+
    
  2. Przeczytaj prostokątny blok znaków i obróć go o ćwierć obrotu w prawo.

    Na przykład dla danych wejściowych

    tye
    xll
    epb
    tma
     id
     sa
    s e
    i r
    hsn
    Tiu
    

    wydrukuj to:

    This  text
    is  simply
    unreadable
    
  3. Przeczytaj liczbę całkowitą od 1 do 40 i wydrukuj diament o tej długości boku.

    Na przykład dla danych wejściowych 3wydrukuj to:

      /\
     /  \
    /    \
    \    /
     \  /
      \/
    
  4. Wydrukuj to:

    ....@@@@....@@@@....@@@@....@@@@
    ....@@@@....@@@@....@@@@....@@@@
    ....@@@@....@@@@....@@@@....@@@@
    @@@@....@@@@....@@@@....@@@@....
    @@@@....@@@@....@@@@....@@@@....
    @@@@....@@@@....@@@@....@@@@....
    ....@@@@....@@@@....@@@@....@@@@
    ....@@@@....@@@@....@@@@....@@@@
    ....@@@@....@@@@....@@@@....@@@@
    @@@@....@@@@....@@@@....@@@@....
    @@@@....@@@@....@@@@....@@@@....
    @@@@....@@@@....@@@@....@@@@....
    ....@@@@....@@@@....@@@@....@@@@
    ....@@@@....@@@@....@@@@....@@@@
    ....@@@@....@@@@....@@@@....@@@@
    @@@@....@@@@....@@@@....@@@@....
    @@@@....@@@@....@@@@....@@@@....
    @@@@....@@@@....@@@@....@@@@....
    ....@@@@....@@@@....@@@@....@@@@
    ....@@@@....@@@@....@@@@....@@@@
    ....@@@@....@@@@....@@@@....@@@@
    @@@@....@@@@....@@@@....@@@@....
    @@@@....@@@@....@@@@....@@@@....
    @@@@....@@@@....@@@@....@@@@....
    

Punktacja

Odpowiedź, która udaje się włączyć największą liczbę programów do jednego pliku, który mieści się w pojedynczym 512-bajtowym klastrze, wygrywa. Więzy są dzielone według liczby bajtów (im niższy, tym lepiej).

Dodatkowe zasady

  • Dla każdego zadania, o które prosi się o wynik, ten sam plik (bajt na bajt) musi stanowić pełny program - w wybranym języku - który rozwiązuje to konkretne zadanie.

  • Każde zadanie musi zostać rozwiązane w innym języku.

    Języki liczą się jako różne, jeśli nie są różnymi wersjami tego samego języka. Na przykład jest tylko jeden JavaScript, jeden Python i jeden TI-BASIC, ale C, C ++, Octave i MATLAB to cztery różne języki.

  • Wybrany język dla każdego zadania musi spełniać naszą zwykłą definicję języka programowania .

    Ponadto język musi zostać opublikowany i wdrożony przed 9 września 2015 r.

  • Twój kompilator / tłumacz może nie wymagać żadnych niestandardowych flag, aby uzyskać oczekiwane zachowanie.

    Wyjątki od tej reguły obejmują flagi wymagane do określenia konkretnego języka, do odczytania programu z (pojedynczego) pliku lub do wyłączenia banera.

  • Dane wejściowe dla każdego zadania będą składały się z drukowalnych znaków ASCII (0x20 do 0x7E) i kanałów (0x0A) i nie będą przekraczać 255 bajtów.

  • Wszystkie liczby całkowite można odczytać w postaci dziesiętnej lub jednostkowej, chyba że w zadaniu podano inaczej.

  • Zachowanie nieprawidłowych danych wejściowych jest niezdefiniowane.

  • Możesz odczytać dane wejściowe ze STDIN (lub jego najbliższej alternatywy) lub jako argumenty wiersza poleceń.

    Jeśli zadanie wymaga odczytania dwóch elementów danych wejściowych, możesz je odczytać - w dowolnej kolejności - oddzielone jednym bajtowym ogranicznikiem według własnego wyboru, jako osobne argumenty wiersza poleceń lub jeden z STDIN, a drugi jako argument wiersza polecenia.

    Jeśli jednym z elementów wejściowych jest linia, jedynym możliwym ogranicznikiem jest linia.

  • Wydrukuj wyjście do STDOUT (lub najbliższej alternatywy). Wszystkie dane wyjściowe do STDERR zostaną zignorowane.

  • Do każdego zadania obowiązują standardowe zasady .

    W szczególności dotyczy to luk, które są domyślnie zabronione , z wyjątkiem twardego kodowania danych wyjściowych , co jest wyraźnie dozwolone w przypadku tego wyzwania.


1
Czy JavaScript i CoffeeScript są na tyle różne, że można je uznać za różne języki?
Downgoat

Tak, te liczą się jako różne.
Dennis

17
twoje wyzwanie nr 4 to nonsens> :(
Klamka

Cytat: Wszystkie dane wyjściowe do STDERR zostaną zignorowane. Czy to oznacza, że ​​kiedy wywołujemy skrypt / program 2>/dev/nulli uzyskujemy prawidłowe wyjście na standardowe wyjście, to jest w porządku? Tak dla pewności.
Cabbie407

2
@ Cabbie407 Dokładnie. Zgodnie z konsensusem w sprawie meta ta reguła faktycznie ma zastosowanie domyślnie do wszystkich wyzwań. Chciałem tylko upewnić się, że wszyscy byli tego świadomi.
Dennis

Odpowiedzi:


17

12 języków, 418 bajtów

"1\"# &&+.@\""" "" "
#=
''''
<<s
""'("']0=~2base{+}*}
 ?
 :_7/!\_7%!@
"
R"Happy Birthday, "[?S"!"*"
>0[0>i:0(?v:{)?v0n;\!/
$'main';n1< .95<
 \@-[I love tabs!]o#
  \ >qi---@
( @-[ ]e<''';print hex(
input())#-[I hate spaces!]o#"]];ri:X{_~X+S*'/@S*_'\4$N}%_sW%1>"))?(!?)
'''=#print(([1 1;1 0]^int(readline()))[1,2])
#=
Tr is here.
>Tr, Hello, World!
>X Tr
s
l=gets
a='+-'+?-*~/$/+'-+'
puts a+'
| %s |
'%l+a#=#.91<0#'''#";

To zabawne wyzwanie. Trudno jest zmieścić więcej języków, ale przy tak wielu bajtach prawdopodobnie mógłbym zrobić jeszcze jeden.

Korzysta bezpłatnie z języków 2D. Zauważ, że znak na między [ ]na @-[ ]e<linii jest zakładka. Wymaga to również \nzakończenia linii dla TRANSCRIPT do działania.

Preludium (Zadanie 1 / Kot)

( 
      )?(!?)

?(!?)to tylko bezpośrednie tłumaczenie ,[.,]w BF. ()Pętle Preludium działają jak []pętle BF , więc wszystko, od (lewej kolumny do )poprzedzającej niewykonywanie programu głównego.

Reguły składniowe Prelude oznaczają, że nawiasy muszą być dopasowane (czytanie od lewej do prawej kolumny), i może być tylko jeden nawias na kolumnę. Poza tym jest to dość łatwy do dopasowania język.

Upewnij się, że NUMERIC_OUTPUTjest ustawiony na, Falsejeśli używasz interpretera Python.

TRANSCRIPT (Zadanie 2 / Witaj świecie)

Tr is here.
>Tr, Hello, World!
>X Tr

TRANSCRIPT to esolang tematyczny oparty na interaktywnej fikcji. Linie nierozpoznane przez TRANSCRIPT są ignorowane, co ułatwia dopasowanie.

Tr is here.deklaruje Trzmienną łańcuchową, a drugi wiersz ustawia zawartość zmiennej na Hello, World!. X Tr( Xdo sprawdzenia) następnie wyprowadza ciąg.

Mimo że TRANSCRIPT jest bardzo łatwy do dopasowania, jest to dość pełny język, więc podjąłem najłatwiejsze wyzwanie.

Rozszczepienie (zadanie 3 / wiadomość urodzinowa)

R"Happy Birthday, "[?S"!"*
                   \!/

który drukuje pierwszą część, umieszcza dane wejściowe za pomocą małej pętli 2D, a następnie generuje końcowy wykrzyknik. Te Roznacza, że atom zaczyna się tutaj przesuwając w prawo, co jest przydatne, ponieważ program ten może być przesuwane w dowolnym miejscu.

Szyna (zadanie 4 / karty)

$'main'
 \@-[I love tabs!]o#
  \ >qi---@
  @-[ ]e<
         -[I hate spaces!]o#

Podobnie jak Fission, Rail jest językiem 2D, który ma tę zaletę, że można go przenosić w dowolnym miejscu. Rozpoczyna wykonawcze z $tego mainfunkcji, kierując się na południowy wschód.

Najpierw kierujemy się w dół \, skręcamy w lewo o -, uderzając, [<tab>]co popycha kartę. e<następnie gałęzie oparte na EOF - jeśli EOF, idziemy w dół i drukujemy "I hate spaces!"przed zatrzymaniem, w przeciwnym razie podnosimy się. Jeśli ruszyliśmy w górę, czytamy następny znak i porównujemy go z tabulatorem, ponownie rozgałęziając się - jeśli tab, skieruj w górę i wydrukuj "I love tabs!"przed zatrzymaniem, w przeciwnym razie skieruj w dół i kontynuuj pętlę wejściową.

Ten program jest dość drogi, ale odkąd TRANSCRIPT zajął Hello World, trudno było wybrać i wykonać odpowiednie zadanie dla Rail.

> <> (Zadanie 6 / Wejście rosnące)

"1\"#      \""" "" "


>0[0>i:0(?v:{)?v0n;
       ;n1< .95<


        .91<

Drukuje, 1jeśli ściśle rosnące, w 0przeciwnym razie.

> <> to inny język 2D, a wykonywanie rozpoczyna się od lewego górnego rogu. "..."jest trybem strunowym, przesuwając znaki wewnętrzne jeden po drugim. Po pierwszym łańcuchu uderzamy #, co odbija IP w lewo, popychając więcej łańcuchów i owijając się (> <> jest toroidalne) przed uderzeniem \, lustro, które odbija nas w górę.

Na dole programu znajduje się .91<teleportujący nas (9, 1)tam, gdzie znajduje się program podstawowy. Po tym 0[usuwa wszystkie śmieci z ciągów, 0wypycha zero, aby reprezentować ostatni odczyt znaku, a następnie po prostu odczytuje znaki jeden po drugim, upewniając się, że wciąż rośniemy.

Prawdopodobnie lepiej jest przenieść program podstawowy niż teleportować się, ale w razie potrzeby zajmę się tym później.

Befunge (Zadanie 9 / Dodawanie)

"1\"# &&+.@

Testowany z tłumaczem znalezionym tutaj . Jest to dość prosty program, z początkiem pchania niepotrzebnego sznurka i #przeskakiwania przestrzeni. Potem jest to tylko program podstawowy &&+.@.

Labirynt (Zadanie 10 / Divmod przez 7)

"1
 =
 '
 <
""'("']
 ?
 :_7/!\_7%!@

Dogodnie, 'i "są NOP w Labiryncie, które działają jak ścieżka w labiryncie. Pominąłem niechlujną nawigację, ale w zasadzie dużo się kręci i wędruje, zanim dotrzemy do ?, co jest początkiem podstawowego programu.

Program nie jest całkiem opróżniony, aby uwzględnić Preludium (np. ?Czyta wejście w Preludium).

Python 2 (Zadanie 14 / Szesnastkowy)

"1\"# &&+.@\""" "" "
#=
''''
xxx
xxx''';print hex(
input())#xxx
'''
xxx
xxx'''#";

Do xxxs reprezentować nieistotnych części wykomentowane przez ciągi multilinii lub komentarze. print hex(input())Pośrodku jest podstawowy program. Daje to wynik wiodący 0x, ale zakładam, że jest w porządku (jeśli nie, to i tak jest to łatwa naprawa).

Pierwszy wiersz to ciąg znaków, "1\"# &&+.@\""po którym następują dwa " "s. Te trzy ciągi są łączone przez parser i pozostawione nieużywane (ta pierwsza linia działa podobnie dla Ruby i Julii później).

GolfScript (Zadanie 15 / Ciężar Hamminga)

"1\"# &&+.@\""" "" "
#=
''''
<<s
""'("']0=~2base{+}*}

Pierwszy wiersz przesuwa trzy ciągi, a drugi wiersz jest komentarzem. ''''wypycha dwa kolejne ciągi, a następnie <<wykonuje dwa porównania ( sjest ignorowane). Wreszcie ""'("'popycha kolejne dwa ciągi.

Wszystko to polega na tym, że śmieci są następnie usuwane przez zawinięcie ich w tablicę i uzyskanie pierwszego elementu ( ]0=), który jest początkowo danymi wejściowymi na stosie. Następnie oceniamy dane wejściowe za pomocą ~, zamieniamy na binarne, a 2basenastępnie sumujemy bity za pomocą {+}*. Następny }nie ma sobie równych i super-komentuje resztę programu.

Julia (Zadanie 16, Fibonacci)

"1\"# &&+.@\""" "" "
#=
xxx
xxx=#print(([1 1;1 0]^int(readline()))[1,2])
#=
xxx
xxx=#.91<0#xxx

#=rozpoczyna komentarz wielowierszowy i =#kończy komentarz wielowierszowy. Program podstawowy wykorzystuje potęgowanie macierzowe do obliczania liczb Fibonacciego (wzięte z Rosetty ).

Ruby (ramka Zadanie 17 / ASCII)

"1\"# &&+.@\""" "" "
#=
''''
<<s
xxx
s
l=gets
a='+-'+?-*~/$/+'-+'
puts a+'
| %s |
'%l+a#xxx

Ten program zakłada, że ​​wejście nie kończy się końcowym znakiem nowej linii.

Mamy niepotrzebny ciąg, komentarz, kolejny niepotrzebny ciąg, a następnie heredoc, który komentuje większość programu. Potem jest program podstawowy, po którym następuje #komentarz w jednym wierszu .

CJam (Zadanie 19 / Diament)

"1\"# &&+.@\""" "" "
#=
''''
<<s
""'("xxx
"
R"xxx"[?S"!"*"
xxx
xxx"ri:X{_~X+S*'/@S*_'\4$N}%_sW%1>"xxx
xxx
xxx";

Dwa ciągi spacji na końcu pierwszego wiersza mają zaspokoić CJam, ponieważ #=są to dwa operatory binarne. Nie będę wchodził w szczegóły w ten temat, ale w zasadzie jest to bałagan, a program podstawowy jest zwykły

ri:X{_~X+S*'/@S*_'\4$N}%_sW%1>

pomiędzy.

Kluczowym czynnikiem odróżniającym GolfScript od CJam jest to, że w CJam pojedynczy cytat 'nie zaczyna i nie kończy ciągów, a zamiast tego wypycha następny znak na stos. Oznacza to, że w CJam

'("'

wypycha a (następnie rozpoczyna ciąg od "(którego pierwszym charakterem jest '), podczas gdy powyższy jest tylko prostym pojedynczym ciągiem w GolfScript.

Wypróbuj online . 1>jest używany zamiast (konta Preludium.


Oto 12 języków, 373 bajtów . Niektóre zadania zostały przeniesione, TRANSCRIPT został usunięty (co spowodowało, że Rail był zbyt drogi) i dodano Schemat (kurczak). To tylko moje pole golfowe dla przyszłych aktualizacji, ponieważ aktualizacja głównego postu trwa wiecznie.

"1\"09!#.&&+.@"" "" "#|"
#=
''''
<<s
11]0=~2base{+}*}
 ?
 :_7/!\_7%!@
"
R"Happy Birthday, "[?S"!"*"
>0[0>i:0(?v:{)?v0n;\!/
$'main';n1< .95<
(-[Hello, World!]o#''';print(input()in input());'''"]];ri:X{_~X+S*'/@S*_'\4$N}%_sW%1>"=#print(([1 1;1 0]^int(readline()))[1,2])#=)?(!?)
s
l=gets
a='+-'+?-*~/$/+'-+'
puts a+'
| %s |
'%l+a# =##'''#";e# |#(print(format"~x"(eval(read))))

Mógłbym zaoszczędzić kilka bajtów dla Julii, ponieważ niezakończone komentarze wielowierszowe zgłaszają błąd do STDERR.


Świetna sprawa. Jakie jest zadanie TRANSCRIPT?
Cabbie407

@ Cabbie407 Wciąż próbuję zoptymalizować, który język pobiera jakie zadanie, ale obecnie TRANSCRIPT przejął Hello World, a Rail zmienił się w zadanie kart.
Sp3000,

Ach, teraz widzę, ;)że zwlekam, zmieniając cokolwiek w mojej odpowiedzi, z powodu długiego opisu. lol
Cabbie407

26

7 8 9 10 języków, 398 431 447 507 bajtów

To chyba najbardziej pasuję do obecnego rozwiązania.

#if      + 0+0/*^",v  +- '[.,][[" ,yadhtrib yppaH"l?!;offf4+ + +0.0 +aa<*/
a=0--0;b=input();print(sorted(set(b))==list(b));[[""""                 ^ <
print("Hello, World!")--[[vv? +<
#endif/*  >.!0 + +1ffr"!"~< */
#include<stdio.h>/*>:1 +?!^>i:1^*/
int main(){int a=1,b=1,c,i;scanf("%d",&i);if(1//**/1==2
){printf("%x",/*>&:7/.7%.@*/i);}else{for(;--i-1>0;a=b,b=c)c=a +b;printf("%d",b);}}/*]]--"""]];#@;_J + + \+*\-hhlz \+s[\|dzd\|)J "` + +,*.]]]*/SSSTNSSNSNSTNTTTTTSSSTNSNSTNTTTTTTSSTNTTSNSSNNSSSNTTTTNSTNNNN

Ostatni wiersz zawiera kod Białej spacji, tak aby SE go nie zjadł. Aby uruchomić kod, zamień wszystko Sspacjami, Ttabulatorami i Nznakami nowej linii.

C89, zadanie 16

Oto, co widzi kompilator:

int main(){int a=1,b=1,c,i;scanf("%d",&i);if(1/ 1==2
){printf("%x",i);}else{for(;--i-1>0;a=b,b=c)c=a+b;printf("%d",b);}}

Cała reszta jest usuwana jako komentarze lub wewnątrz #if 0.

C ++, zadanie 14

Użyłem sztuczki skradzionej stąd, aby odróżnić C89 od C ++.

int main(){int a=1,b=1,c,i;scanf("%d",&i);if(1
){printf("%x",i);}else{for(;--i-1>0;a=b,b=c)c=a+b;printf("%d",b);}}

Lua, zadanie 2

Oto podstawowa struktura.

#comment
a=0--comment
print("Hello, World!")--[[
... multiline comment ...
]]--comment

Brainfuck, zadanie 1

Musiałem tylko upewnić się, że nie .,zostaną znalezione nieskończone pętle lub zbłąkane . Komentarze wieloliniowe Lui również podwojają się z komentarzami BF. Wszystko oprócz pierwszych 2 znaków to duża pętla NOP.

++,+-[.,][[,+++.+<--[[<,--[[+<>.++<<.>>+>,,,,,>..--->,+,]]--]]+++-+[++,.]]]

Python, zadanie 6

Ponownie używam funkcji specyficznych dla języka, aby NOP lub skomentować inny kod.

#comment
a=0--0;b=input();print(sorted(b)==list(b));[["""
... multiline string ...
"""]];#comment

Pyth, zadanie 17

Pyth jest do tego miły. Pobiera pierwszą #jako while True:pętlę, która cicho wychodzi po błędzie . Tak więc po prostu robię większość kodu jako ciąg znaków (aby uniknąć wcześniejszego ;zakończenia pętli), a następnie po prostu kończę pętlę, wychodzę z innego utworzonego przez komentarz Pythona i wykonuję zadanie. Oto wszystkie zastąpione niepustymi ciągami " string ", wciąż funkcjonalnie równoważne:

#if      + 0+0/*^" string " ,yadhtrib yppaH" string """" string "Hello, World!" string "!"  string "%d"  string "%x" string "%d" string """]];#@;_J + + \+*\-hhlz \+s[\|dzd\|)J " string

> <>, zadanie 3

Ten jest bardzo interesujący. Wykonanie odbija się w kodzie, używając skoków, aby ominąć przeszkody. Odpowiednie części:

#                  v            " ,yadhtrib yppaH"l?!;offf4+ + +0.0 +aa<*/
                   i                                                   ^ <
                   !      vv? +<
          >.!0 + +1ffr"!"~<
                   >:1 +?!^>i:1^

Gwiaździsta , zadanie 9

Tutaj zacząłem wchodzić w języki „odrzucaj wszystkie postacie oprócz”. Cokolwiek innego się rozebra, wygląda to tak:

      + +*,  + '., , + + +. +*                  ,  +*  . + + *.* +*  ,,,,**,*..*, +,* + + +* + ` + +,*.*

Kod przeskakuje większość interpunkcji za pomocą skoku, aby uniknąć trudności, wystarczy użyć początku i końca kodu. Kod jest funkcjonalnie równoważny z

      + +*,  + + +,*.*

Befunge-98, zadanie 10

Działa podobnie do>>. Na szczęście #jest lustrem w> <> i pominięciem w Befunge, więc możemy zastosować inne zachowanie. Również 0/0 == 0.

#if      + 0+0/*^
                >&:7/.7%.@

Biała spacja , zadanie 13

To była ostatnia rzecz, do której pasowałem. Pierwsze kilka linii po prostu wypycha zera na stos, ponieważ zawierają tylko spacje i znaki nowej linii z „normalnego” kodu. Kod jest zakodowany; zamień wszystko Sspacją, Ttabulatorami i Nznakami nowej linii.

SSSSSSSSSSSSSSSN
SSSSSSSSSSSSSSSSSSN
SSN
SSSSSN
SN
SSN
SSSSSSSSSSSTN
SSN
SN
STN
TTTTTSSSTN
SN
STN
TTTTTTSSTN
TTSN
SSN
N
SSSN
TTTTN
STN
N
N

9

17 różnych wersji Pipa, 383 bajtów (nieprawidłowy)

Podczas gdy to pytanie było piaskownicą, przeczesałem wszystkie wersje mojego języka Pip i wymyśliłem poliglota, używając 17 z nich. Niestety, wersje tego samego języka są obecnie niedozwolone w regułach wyzwania, ale i tak za zgodą Dennisa i zrzeczeniem się zamieszczam swoją pracę.

Surowy kod

I!ga:0m@0:0v:uIN[(oTM0,0i)EN1N1Y1RCkw(hR`1.+0``&2o`)@>3@AB0`u`rZ4AB6({a}V7)BN8AZ9@m]Iv<2W##YqlPByc:((J['.'@]X4)X4RL3)Jnc.:n.RVcc:cRL4|0Iv=3{d:sXaRLaFj,ad@j@j:'\d:(RVdR'\'/).d|0dJ:n}m:'+.'-X#a+2.'+.n."| "Iv=5La{i+:oSio}j:ak:bPv=11?a>1&0INa%(2,a)[((J_M ZRVl)|0)Jnl?lJnlcJnd.n.RVdm.a.RVmih:$+TBa({j@aEQk}FI0,#a).saTB16a>b?abh=1ua//7.s.a%7a+bbINa"Happy Birthday, ".a.'!"Hello, World!"]@v

Strategia

W Pip małe litery są zmiennymi. Wielkie litery są bardziej skomplikowane: są podzielone na ciągi najwyżej dwóch znaków, którymi mogą być operatory lub zmienne. Jeśli token wielkich liter nie jest specjalnie zdefiniowany jako zmienna lub operator, zakłada się, że jest to niezdefiniowana zmienna, której wartość wynosi zero.

Tak więc, aby rozróżnić dwie wersje Pipa, muszę tylko znaleźć operator zmiennej lub alfabetyczny, który został dodany w nowszej z nich. W starszym będzie to zero. Kod v:uIN[...]zestawia dużą listę zawierającą jeden z tych sprawdzeń dla każdej wersji, którą chcę przetestować, dowiaduje się, ile nilów znajduje się na tej liście ( uzmienna jest wyraźnie inicjowana na zero), i przechowuje liczbę w v(dla „wersji”) .

Po kilku innych obliczeniach pojawia się kolejna duża lista, która oblicza wyniki 17 zadań z wyzwania i używa jej vdo wyboru w zależności od wersji.

Wersje i zadania

0.15.09.04

Diagnostyka: (oTM0,0i)(naprawiono błąd z operatorem Tri M, w którym przycinanie 0 znaków z każdego końca łańcucha dawało zamiast tego pusty ciąg; indeksowanie w pusty ciąg daje zero)

Zadanie 18: Iv<2W##YqlPBy(konfiguracja: odczytaj wszystkie linie ze standardowego wejścia, jeśli vjest mniejsza niż 2), a następnie ((J_M ZRVl)|0)Jn(odwróć listę linii, transponuj i ponownie połącz w łańcuch)

0.15.08.06

Diagnostyka: EN1(dodano ENoperator umerate)

Zadanie 1: Iv<2W##YqlPBy(taki sam kod instalacyjny jak powyżej), a następnie l?lJnl(dołącz do nowych linii)

0.15.08.03

Diagnostyka: 1N1(dodana Njako krótka wersja INoperatora)

Zadanie 20: c:((J['.'@]X4)X4RL3)Jnc.:n.RVcc:cRL4|0(konfiguracja: wygeneruj listę zawierającą górną i dolną połowę szachownicy i zapisz c), a następnie cJn(dołącz do nowej linii)

0.15.08.01

Diagnostyka: Y1(dodano Yoperator ank)

Zadanie 19: Iv=3{d:sXaRLaFj,ad@j@j:'\d:(RVdR'\'/).d|0dJ:n}(ustawienie: jeśli vjest 3, zbuduj górną połowę diamentu d), a następnie d.n.RVd(odwróć na dolną połowę i dołącz do nowej linii)

0.15.06.19

Diagnostyka: RCk(dodano operator Random hoice C)

Zadanie 17: m:'+.'-X#a+2.'+.n."| "(setup: build +----+\n| string in m), a następnie m.a.RVm(zawijanie danych wejściowych mi odwracanie m)

0.15.06.12

Diagnostyka: k( kzmienna wstępnie zainicjalizowana na ", "; wcześniej była niezdefiniowana, a zatem zerowa)

Zadanie 16: Iv=5La{i+:oSio}(jeśli vjest to 5, wygeneruj liczbę Fibonacciego i), a następniei

0.15.06.08 (uwaga: numer wersji nie został zmieniony do czasu następnego zatwierdzenia)

Diagnostyka: w( wzmienna wstępnie zainicjalizowana do `\s+`)

Zadanie 15: h:$+TBa(przekonwertuj dane wejściowe na cyfry binarne i sumy; zapisz wynik hdla zadania 12 później)

0.15.05.29

Diagnostyczny: (hR`1.+0``&2o`)@>3@AB0

Ta wersja została dodana &jako wzór zastępczy dla całego dopasowanego łańcucha w zamianie wyrażenia regularnego (zainspirowany przez sed). Powyższy kod przyjmuje h( 100) i zastępuje go `&2o`(tj. "1002o"W nowszych wersjach, ale po prostu "&2o"w starszych wersjach). Następnie wycina wszystkie znaki po trzeciej ( "2o"w nowszych wersjach, ""w starszych wersjach) i próbuje zaindeksować ten ciąg. Indeksowanie w pusty ciąg daje zero.

Zadanie 7: j:ak:b(Setup: kopie lokalne Vars a, bdo globalnych Vars j, kwięc będą one dostępne wewnątrz funkcji), a następnie ({j@aEQk}FI0,#a).s(filtr dla indeksów w aktórym odpowiedni znak równa się bi dołącz na przestrzeni)

0.15.05.26

Diagnostyka: `u`(dodano typ wzorca; we wcześniejszych wersjach znaki wsteczne są ignorowane jako nierozpoznane znaki, a wyrażenie ocenia na u, co jest zerowe)

Zadanie 14: aTB16(konwersja TO Bazę 16)

0.15.05.24

Diagnostyka: rZ4(utworzono rspecjalną zmienną, która zwraca losową wartość od 0 do 1 za każdym razem, gdy się do niej odwołuje; poprzednio była niezdefiniowana, a zatem wyrażenie było oceniane na zero)

Zadanie 13: a>b?ab(wyrażenie trójkowe)

0.15.05.12

Diagnostyka: rZ4(dodano Zoperator ip)

Zadanie 12: h=1(suma bitów z zadania 15 musi wynosić 1)

0.15.05.11

Diagnostyka: AB6( ABoperator dodanej wartości rozpuszczonej)

Zadanie 11: Pv=11?a>1&0INa%(2,a)[...]@v(jeśli vjest to 11, dane 1wyjściowe są większe niż 1, a mniejsza liczba dokładnie je dzieli, w 0przeciwnym razie; jeśli vjest coś innego, użyj vjako indeksu na liście, aby zdecydować, co wydrukować)

0.15.05.02

Diagnostyka: ({a}V7)(dodany Voperator; gdy nie Vzostał zdefiniowany, wysłał argumenty zero i 7 do funkcji, {a}która zwraca swój pierwszy argument)

Zadanie 10: a//7.s.a%7(dane wejściowe podzielone przez 7 i mod 7, rozdzielone spacjami)

0.15.04.26

Diagnostyka: BN8(dodano operatora Begation Nitwise)

Zadanie 9: a+b

0.15.04.23

Diagnostyka: AZ( AZzmienna wstępnie zainicjowana na wielkie litery)

Zadanie 5: bINa( INpodaje liczbę wystąpień)

0.15.04.20

Diagnostyka: m@0:0następnie9@m

mZmiennej preinitialized do 1000. W tym COMMIT @operator został rozwiązany powrotu lwartościami; poprzednio przypisanie do m@0ostrzeżenia i nic nie zrobiło. Zatem po usunięciu błędu pierwsza instrukcja ustawia się mna 0000, która jest legalnym indeksem dla 9; przed poprawką, mpozostaje 1000, co nie jest prawnym indeksem. (Wskaźniki nie były jeszcze cykliczne).

Zadanie 3: "Happy Birthday, ".a.'!

0.15.04.18

Wszystkie poprzednie diagnostyki powodują, że zero jest dodawane do listy diagnostycznej.

Zadanie 2: "Hello, World!"


Większość innych kodów to poprawki, które musiałem wprowadzić, aby uniknąć błędów w różnych wersjach. Ten post jest już zdecydowanie za długi, więc jeśli chcesz wiedzieć o czymś, czego nie wyjaśniłem, przejdźmy do dyskusji na czacie w językach ezoterycznych .


4

6 języków, 226 bajtów (229 w zależności od sposobu \x1bakceptacji!)

/&&#[+.#]@>>+[>,]<[<]>>[.>]>\[/;//;#<?die("\x1bc".max($argv[1],$argv[2]));/*
$a=['Hello','World'];//;printf"%s, %s!
",$a[0]||'Happy Birthday',$a[1]||pop;#";$a="\
#";alert(prompt().match("\t")?"I hate tabs!":"I love spaces!");/\]/

Więc nie sądzę, że dokonałem najlepszego wyboru języków i wyobrażam sobie, że nie jest to szczególnie konkurencyjne, ale mimo to uważałem to za interesujące wyzwanie! Ogólnie rzecz biorąc, nie ukończono wielu wyzwań, ale prawdopodobnie mógłbym zdobyć wyzwanie w spacji lub coś podobnego, ale do tej pory mam to:


1. Brainfuck

[+.]>>+[>,]<[<]>>[.>]>[<.[],[][,],,[],[].]

Testowane na http://copy.sh/brainfuck/ i http://brainfuck.tk/ .

Po usunięciu wszystkich ignorowanych znaków, powyższy program jest wszystkim, co nam pozostało, jest to tylko przykładowy program cat z dodatkowymi pustymi pętlami, aby ominąć użycie symboli w innych językach.

2. Ruby

/&&#[+.#]@>>+[>,]<[<]>>[.>]>\[/;//;
$a=['Hello','World'];//;printf"%s, %s!
",$a[0]||'Happy Birthday',$a[1]||pop;

Stosowanie:

ruby cluster

Powyższy kod jest po usunięciu wszystkich komentarzy. Pierwsza linia jest całkowicie bezużyteczne w Ruby jak możemy zdefiniować kilka wyrażeń regularnych zawiera kod befunge-93 i brainfuck, następnie tworzymy tablicę, aby zawierał Helloi Worldi wydrukować go za pomocą printf(aby dodać ,a !).

3. Perl

/&&#[+.#]@>>+[>,]<[<]>>[.>]>\[/;//;
$a=['Hello','World'];//;printf"%s, %s!
",$a[0]||'Happy Birthday',$a[1]||pop;

Stosowanie:

perl cluster <name>

Bardzo podobny do Ruby, z tą różnicą, że ponieważ przechowujemy odwołanie do tablicy $a, kiedy próbujemy uzyskać do $a[0]niego dostęp , jest ono puste, więc możemy zastąpić go tekstem dla wyzwania 3 Happy Birthdayi pop(który pokazuje ostatni argument programu wiersza poleceń ).

4. JavaScript

/&&#[+.#]@>>+[>,]<[<]>>[.>]>\[/;
$a=['Hello','World'];
",$a[0]||'Happy Birthday',$a[1]||pop;#";$a="\
#";alert(prompt().match("\t")?"I hate tabs!":"I love spaces!");/\]/

Sposób użycia: wklej do konsoli przeglądarki i uruchom.

Podobnie jak Ruby i Perl, pierwszy wiersz zasadniczo tworzy bezużyteczne RegExpobiekty, następnie przechowujemy bezużyteczną tablicę $ai tworzymy instancję dwóch bezużytecznych ciągów, z których jeden zawiera kod Ruby / Perl, a drugi zawiera znak nowej linii #, a następnie mamy prompt()dane wejściowe i alert()oczekiwany wynik przez większość ludzi na wyzwanie 4. Kończymy kolejnym bezużytecznym RegExpprzedmiotem, który zamyka pętlę pieprzenia mózgu.

9. Befunge-93

/&&#[+.#]@

Testowany na http://www.quirkster.com/iano/js/befunge.html .

Jak rozumiem, /dzieli stos i wypycha wynik, który nie ma negatywnych skutków poza wypychaniem NaNna powyższą stronę, &prosi o wprowadzenie liczby całkowitej, więc odczytujemy na stosie obie liczby wymagane przez wyzwanie 9 na stosie, #zapewnia to pominięcie [który jest do wykonania, aby przelecieć mózg, +a następnie dodaje dwie górne liczby ze stosu, .wysyła je, #]by znów przelecieć mózg i @wychodzi.

13. PHP (działający w Bash)

/&&#[+.#]@>>+[>,]<[<]>>[.>]>\[/;//;#<?die("\x1bc".max($argv[1],$argv[2]));

Stosowanie:

php cluster <x> <y>

W PHP wszystko, co nie jest zawarte w <?tagach, jest wypisywane dosłownie, więc wypisuje kod Befunge-93 i kod typu „brainfuck”, więc die()natychmiast w kodzie wypisujemy screen clear ( \x1bc), a następnie max()dwa pierwsze argumenty.


Możesz wstawić literalny znak ESCape w literał łańcuchowy, po prostu dodaj notatkę, że tam jest ( the first character in the first string literal is the byte ASCII 27); twój wynik to 226.
kot

@cat Tak, myślę, że masz rację, na razie odszedłem na obecną wersję, ale umieściłem 226 w tytule. Zapomniałem, jak bardzo podobało mi się to wyzwanie, prawdopodobnie mógłbym teraz zrobić trochę więcej, a używając ES6 mógłbym .match'\x09'(tam gdzie są) być może zobaczę, czy w pewnym momencie mogę dodać więcej!
Dom Hastings,

4

6 języków, 450 404 bajtów

bash, brainfuck, C, gawk4, JavaScript i Minimal-2D

/*\t/#[R,+/D
/\t/ # UL.-L<script>var s=prompt().split(' ');alert(+s.pop()+ +s.pop())</script>
sed "s/^\(.*\)$/Happy Birthday, &!/;q"&&0
/\t/#*/
#define func
func main(){puts("Hello, World!");}
//{split($0,b,_);for(i in b)a[NR][i]=b[i++]}END{for(;j++<i;print"")for(k=NR;k;)printf a[k--][j]}
#//]++++++++[>+>+>++++++>++++++++<<<<-]>>++>--<<[>>>>>+++[<++++[<<....>....>-]<<<.>>>>-]<<<[>>+<<-]<[[>+<-]<]>>-]

Aktualizacja: trochę golfa. Nadal nie jestem pewien, co jeszcze dodać, i nie jestem pewien, jak konkurujący członkowie pomyśleliby o mnie, używając ich języków do różnych zadań. Próba wyjaśnienia algorytmu pieprzenia mózgu.

To było moje pierwsze doświadczenie z poliglotą, więc musiałem nauczyć się wszystkiego od zera. Rozpoczęcie od awk nie było najmądrzejszym pomysłem, ponieważ wydaje mi się, że jest względnie bezlitosny. Ponieważ liczba wykonanych zadań jest istotna, najpierw zacząłem od najłatwiejszych zadań. Nie jestem pewien, czy to był mądry ruch. Nie jest to zbytnio grało w golfa, ponieważ miałem wystarczająco dużo problemów ze współpracą tych sześciu, ale zrobiłem, co mogłem, żeby to krótko potrwać.

Oto języki i ich czynności w kolejności alfabetycznej. Pokażę prosty sposób przetestowania ich wszystkich w dalszej części. Ponieważ niektóre z nich mogą być specyficzne dla wersji, podam numery wersji używanych przeze mnie narzędzi.

uderzenie, zadanie 3

Cóż, to oczywiste, że użyłem sed. Próbowałem w jakiś sposób umieścić skrypt sed, ale nie mogłem go uruchomić, więc poszedłem na bash. Sposób, w jaki to robię, jest w komentarzu C i awk ocenia to False.

sed --version daje sed (GNU sed) 4.2.2

bash --version daje GNU bash, Version 4.3.30(1)-release (x86_64-pc-linux-gnu)

Więc część sed sprowadza się do

sed "s/^\(.*\)$/Happy Birthday, &!/;q"

Grupuje dane wejściowe, wkleja je w nowy ciąg i wypisuje wynik. Dość powszechne rzeczy.

pieprzenie mózgu, zadanie 20

Cóż, to chyba zawsze jest dość łatwe do ukrycia. Linia rozpoczynająca się od #//jest ignorowana przez C i awk. A przynajmniej mogą żyć za śmieciami.

bf daje bf - a Brainfuck interpreter version 20041219

To jest kod skondensowany. Pierwszy wiersz to tylko śmieci z innych języków.

[,+.-<>.+.++.<>.,,,,[][][++]++<[--][]]
++++++++[>+>+>++++++>++++++++<<<<-]>>++>--<<
[>>>>>+++[<++++[<<....>....>-]<<<.>>>>-]<<<[>>+<<-]<[[>+<-]<]>>-]

Spróbuję wyjaśnić, jak to działa

++++++++[>+>+>++++++>++++++++<<<<-]>>++>--<<

ustawia to taśmę i wskaźnik do tego

0 8 10 46 64 C2 C1
  ^

komórka zawierająca 8 jest globalnym licznikiem dla następnej pętli
, jest to liczba wydruków 3 takich samych linii

[>>>>>+++

ustawia C1na 3, liczbę takich samych linii

    [<++++

ustawia C2na 4, liczbę „ ....@@@@” w wierszu (na początku)

        [<<....>....>-]<<<.>>>
    >-]

wypisuje całkowite zmniejszanie linii C2w procesie,
gdy C2wynosi zero, drukuje nową linię i zmniejsza C1.

jeśli C1wynosi zero, magia się dzieje

    <<<[>>+<<-]
    <[[>+<-]<]

46 przesuwa się za 64
10, a licznik globalny przesuwa się o jeden w prawo

>>-]

wtedy globalny licznik jest zmniejszany,
jeśli wynosi zero, program kończy pracę

C, zadanie 2

Wyczerpuję każdą ostatnią zdolność C tutaj, drukując „Witaj, świecie!”. Cóż, ktoś musiał wykonać robotę ...

gcc --version daje gcc (Ubuntu 4.9.2-10ubuntu13) 4.9.2

Rzeczywisty kod C.

#define func
func main(){puts("Hello, World!");}
#

#define funcJest, aby awk w porządku z tym. Uważa, że ​​jest to funkcja awk. Skrót od func to cecha gawk.

gawk4, zadanie 18

Ponieważ użyłem awk do prawie wszystkiego tutaj, zdecydowałem, że to musi być w tym.

awk --version daje GNU Awk 4.1.1, API: 1.1 (GNU MPFR 3.1.2-p11, GNU MP 6.0.0)

awk to widzi

/*\t/
/\t/
sed "s/^\(.*\)$/Happy Birthday, &!/;q"&&0
/\t/
func main(){puts("Hello, World!");}
//{split($0,b,_);for(i in b)a[NR][i]=b[i++]}END{for(;j++<i;print"")for(k=NR;k;)printf a[k--][j]}
#

Wzorce wyszukiwania, w tym \tocena do false. Wybrałem tutaj kartę, ponieważ myślę, że nie może być w danych wejściowych. sedocenia na false. "the string"&&0ocenia na fałsz. Funkcja jest w porządku. Program jest wykonywany, jeśli dopasowany jest pusty wzorzec, który jest dla dowolnego wejścia.

Robi to

Wkład

elaiczny
parli
ucfit
srigs

Wydajność

supe
rcal
ifra
Gili
stic

Musisz upewnić się, że wszystkie linie wejściowe mają tę samą długość. Wypełnij je spacjami.

JavaScript, zadanie 9

Nie jestem pewien, czy jest to uzasadnione, ponieważ było to zbyt łatwe. Jeśli nadasz plikowi programowemu końcówkę HTML i otworzysz go w przeglądarce (korzystałem z przeglądarki Firefox 40.0.3 i Chrome 45.0.2454.85), pojawi się monit o podanie danych wejściowych. Musisz wprowadzić dwie liczby oddzielone spacją, a alarm wyświetli ich sumę.

<script>var s=prompt().split(' ');alert(+s.pop()+ +s.pop())</script>

Minimal-2D , zadanie 1

Łatwo było to zmieścić w liniach komentarzy. Do przetestowania tego użyłem interpretera działającego w Pythonie. Drukuje dane wejściowe na wyjściu. Program wygląda następująco

R,+/D
UL.-L

RUDL są w prawo, w górę, w dół i w lewo. Więc zaczyna iść w prawo, wczytuje postać ze standardowego wejścia do pamięci i dodaje jedną. Ukośnik pomija następne polecenie, jeśli pamięć ma wartość 0. To ma to zakończyć. Jeśli zostanie odczytany znak o wartości -1, wprowadzanie zakończy się. Więc jeśli -1 zostanie odczytane, pomija D i kończy. Jeśli czytane jest coś innego, idzie w dół w lewo, dodaje to 1 z powrotem do pamięci i drukuje postać na standardowe wyjście. Potem idzie w lewo i w górę i zaczyna od nowa.

Testowanie

Oświadczenie: Nie będę ponosić żadnej odpowiedzialności za jakiekolwiek szkody wyrządzone w tym systemie.

Zakłada się, że masz bash & co, gawk (przynajmniej wersja 4, ponieważ używa to tablic wielowymiarowych), gcc, python, bf jako interpreter pieprzenia mózgów i zainstalowany Firefox.

Aby to ułatwić, skopiuj źródło programu do pliku o nazwie cluster.html. Udostępnij ten plik jako wykonywalny dla zadania bash. Skopiuj i wklej interpreter dla Minimal-2d do pliku o nazwie minimal2D.pyw tym samym katalogu. Następnie skopiuj i wklej poniższy skrypt do pliku skryptu i umieść go w tym samym katalogu, spraw, by był wykonywalny i uruchom go ... no cóż, z kim rozmawiam. Jeśli to przeczytasz, prawdopodobnie nie potrzebujesz aż tyle wyjaśnień i i tak sprawisz, żeby jakoś działało.

#!/bin/bash
# Task  3: bash
echo "Dr. Hfuhruhurr" | ./cluster.html 2>/dev/null;echo
# Task 18: awk 
printf "elaic\nparli\nucfit\nsrigs\n" | awk -f cluster.html 2>/dev/null;echo
# Task  2: C
cp ./cluster.html ./cluster.c;gcc -w -o cluster cluster.c;./cluster;rm cluster cluster.c;echo
# Task  1: Minimal-2D
python minimal2D.py cluster.html <<<"This
has
to be
copied     !!!";echo
# Task 20: brainfuck
bf cluster.html;echo
# Task  9: JavaScript
firefox cluster.html 2>/dev/null
#google-chrome cluster.html 2>/dev/null

Tam też znajduje się polecenie uruchamiania poszczególnych testów.

Baw się dobrze!


Ten pieprzony mózg ma problem; kod ma niesymetryczne nawiasy kwadratowe i nie działa poprawnie (musisz uruchomić cały plik, a nie tylko odpowiednią część). Ponadto kwadraty szachownicy mają w rzeczywistości 4x3 zamiast 4x4, aby wyglądać bardziej kwadratowo w tekście.
PurkkaKoodari

Dzięki za podpowiedź. Cóż, tutaj działa dobrze. Zawsze uruchamiam cały plik, jak widać w moim skrypcie. Nie jestem pewien, czy tłumacz powinien sprawdzić nawiasy przed uruchomieniem. Mój nie ma nic przeciwko. Ale przeoczyłem tę liczbę linii. Muszę to zmienić.
Cabbie407,

Cóż, zaglądałem ponownie i mam nadzieję, że to naprawiłem.
Cabbie407,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.