Wystaw się wobec długich linii


23

Ostatnio ktoś zaproponował bardziej rygorystyczne ograniczenia domyślnej długości linii Pythona:

Oczywiście żaden program nie powinien używać więcej niż 80 znaków w wierszu, z wielu powodów. Przede wszystkim, dla czytelności i łatwości konserwacji, ważne jest, aby mieć solidny standard, abyśmy mogli odpowiednio dostosować szerokość naszych edytorów tekstu. Dodatkową korzyścią jest to, że kod można łatwo przenieść na nośnik, który może mieć ograniczenia, a dodawanie podziałów linii może rozpraszać uwagę, np. Drukowanie stron do recenzji na spotkaniu lub dziurkowanie kart.

Ale czy 80 znaków jest zbyt wysoka? Niektórzy sugerują 79, a nawet 75, aby umożliwić terminalowi o szerokości 80 znaków dopasowanie kodu do kilku kolumn poświęconych numerom linii. Oczywiście ostatecznie niższe jest lepsze, ponieważ dolne limity pozwalają na użycie kodu w większej liczbie sytuacji bez ponownego formatowania.

Przedstawiamy standard max6

Twoim celem jest znalezienie i zademonstrowanie minimalnej długości linii wymaganej przez Twój ulubiony język, pisząc wariant FizzBuzz z najmniejszą liczbą znaków w dowolnej linii.

Wkład

Liczba całkowita, n , dowolną pożądaną metodą.

Wydajność

Wydrukuj liczby od 1 do n , ( n ≥ 1, n ∈ ℤ) oddzielone łamaniem linii, z wyjątkiem:

  • dla wielokrotności 3 wydruków „Apple”
  • dla wielokrotności 5 wydruków „Pie”
  • dla wielokrotności druku 3 i 5 „ApplePie”

Punktacja

Maksymalna długość linii w bajtach, nie uwzględniając podziału linii (Cr, CrLf, Lf lub innego standardowego podziału systemu, określ, stosownie do potrzeb), a całkowita długość kodu w bajtach jako przerywacz remisu.

Zasady

Wszystkie podziały linii muszą mieć znaczenie. Podziały linii, które można usunąć, i sąsiednie linie bezpośrednio połączone bez wpływu na wynik, muszą zostać usunięte.


2
W przypadku ograniczenia nowej linii, jeśli usunięcie określonej grupy nowych linii powoduje, że działa, ale usunięcie pojedynczej nowej linii powoduje jej awarię, czy należy usunąć nowe linie? Są one ważne pod względem składniowym, po prostu usunięcie niektórych z nich anuluje ich znaczenie.
Wheat Wizard

3
Nie jestem pewien, co sądzę o „znaczącej” zasadzie nowego wiersza. Jeśli chodzi o składnię prawną, znaczna większość języków programowania nie przejmuje się nowymi liniami i pozwala napisać cały program w jednym wierszu - wystarczy spojrzeć na większość rozwiązań do gry w golfa :-P
nderscore

1
Po co zmieniać go na Apple Pie zamiast standardowego
Rohan Jhunjhunwala

5
@RohanJhunjhunwala Aby zapobiec używaniu wbudowanych poleceń FizzBuzz.
Ørjan Johansen

2
+1 To naprawdę dobry pomysł na wyzwanie w golfa kodu! Niewielka liczba znaków w wierszu wydaje się jednak niepraktyczna 😅 Mimo to uwielbiam
George Willcox

Odpowiedzi:


17

> <> , 1 bajt na linię, 243 161 135 bajtów

-26 bajtów dzięki Jo Kingowi!

Języki 2D FTW! Chociaż pisanie pętli i gałęzi za pomocą instrukcji goto zamiast struktury 2D nie jest zabawne.

v
l
:
:
3
%
:
&
0
4
7
*
&
?
.
~
~
"
e
l
p
p
A
"
o
o
o
o
o
$
5
%
:
&
0
a
5
*
&
?
.
~
~
"
e
i
P
"
o
o
o
*
0
@
?
n
?
~
l
{
:
}
=
?
;
a
o
1

Wypróbuj online! lub obejrzyj na placu zabaw dla ryb !

Ryba płynie w dół wzdłuż kodu, używając warunkowych gotów do pomijania rzeczy w zależności od tego, co dzieli akumulator.

Uważam, że spełnia to specyfikację: bez względu na to, jakie nowe linie są usuwane, ryba zawsze uderza w początkową v(jedyna obecna instrukcja zmieniająca kierunek), więc ryba zawsze płynie w dół w pierwszej kolumnie. W ten sposób usunięcie nowego wiersza powoduje po prostu usunięcie następnego znaku ze ścieżki ryby, i nie sądzę, że można usunąć dowolny znak bez zmiany wyniku.


Ile to bajtów?
L3viathan

1
@ L3viathan, to 243 bajty. (Zmienię to w.)
Nie drzewo

1
@ L3viathan: Zmieniłem nieco to, a teraz ma 161 bajtów!
Nie drzewo

:( Nie sądzę, żebym mógł tak bardzo
pograć w

1
135 bajtów . i tutaj jest wersja pozioma do odniesienia
Jo King

18

Haskell , 3 bajty / linię, 494 471 470 463 453 450 461 bajtów

EDYTOWAĆ:

  • -26 bajtów: Usunięto zbędne łamanie wierszy i związane z nimi znaczniki komentarzy i zmieniono -1+xna x-1.
  • +3 bajty: Ups, potrzebna dodatkowa --linia po x-.
  • -1 bajt: w fużyciu c 47:[]zamiast [c 47&0].
  • -7 bajtów: Przenieś obsługę nowej linii do w.
  • -10 bajtów: Inline a="Apple"i p="Pie"in #i użyj fikcyjnej rekurencji dla przypadku 15.
  • -3 bajty: Inline win f. Usuń zbędne --między xi 15.
  • +11 bajtów: Ups! Moja teoria luki strun ma dziurę. Naprawiono przez wprowadzenie %funkcji. W końcu wykonałem automatyczne testy, aby upewnić się, że nie będzie już niespodzianek.

fbierze Inti zwraca a String.

{;f
n=
--
[--
1..
--
n--
]--
>>=
\
--
x->
--
gcd
x
15#
--
x++
--
c
47:
--
[--
]--
;1#
--
x=
--
n!!
--
(x-
--
1--
)--
;3#
--
_=
--
"A\
\p\
\p\
\l\
\e\
\"&
--
0--
;5#
--
_=
--
"P\
\i\
\e\
\"&
--
0--
;--
15#
--
_=
--
3#
--
0++
--
5#
--
0--
;n=
--
d++
--
[--
s++
--
t|
--
s<-
--
n--
,--
t<-
--
[c
9]:
--
d--
]--
;d=
--
(:
--
[--
]--
)--
<$>
--
[c
8..
--
c
0--
]--
;c
x=
--
[--
"9\
\"%
--
0--
,--
"8\
\"%
--
0..
--
]!!
--
x--
;--
[--
a]%
--
_=
--
a--
;x&
--
y=
--
x}

Wypróbuj online!

Testuj ograniczenia źródła!(Linia 70 jest wykluczona z testowania, ponieważ usunięcie jej nowej linii powoduje nieskończoną pętlę bez wyjścia.)

Wersja z usuniętymi najważniejszymi sztuczkami wyciskającymi:

{;f n=[1..n]>>= \x->gcd x 15#x++c 47:[]
;1#x=n!!(x-1)
;3#_="Apple"
;5#_="Pie"
;15#_=3#0++5#0
;n=d++[s++t|s<-n,t<-[c 9]:d]
;d=(:[])<$>[c 8..c 0]
;c x=["9"%0,"8"%0..]!!x
;[a]%_=a
;x&y=x}

Jak to działa

  • Ten kod jest zapisywany w rzadziej używanym trybie Haskell niewrażliwym na wcięcia, wyzwalanym np. Przez otoczenie całego programu {}. Ponieważ tak naprawdę definiuję funkcję, a nie cały program, nie jestem pewien, jak liczyć bajty; I Wybrano obronnym liczyć zarówno z {}S i dodatkowego ;separatora zgłoszenia (ten ostatni zazwyczaj jest znakiem końca linii, w normalnym trybie Haskell).
  • Główną sztuczką, dzięki której nowe wiersze są „znaczące”, są --komentarze do linii, które sprawiają, że następnej nowej linii nie można usunąć, a także poprzedniej nowej linii w przypadku, gdy poprzednia linia kończy się znakiem operatora (który sam nie jest częścią komentarza linii) .
  • Druga sztuczka to „luki w łańcuchach”, sekwencja białych znaków między \odwrotnymi ukośnikami w literałach łańcuchów, wcięta dla kontynuacji linii z możliwym wcięciem. Przerwa w ciągu znaków z ogranicznikami jest usuwana z przeanalizowanego ciągu.
    • Usunięcie nowej linii odstępu między ciągami powoduje dodanie do niej odwrotnego ukośnika. For "Apple"i "Pie"pokazuje się to bezpośrednio na wyjściu. For "8"i "9"dopasowanie wzorca służy do podania błędu, jeśli łańcuch ma więcej niż jeden znak.
  • Trzecią lewą są operatory &i %, które pozwalają na wymuszenie zakończenia linii znakiem operatora dla pierwszej lewy. Potrzebujemy tego do końca literałów łańcuchowych, ponieważ \"jest zbyt szeroki, aby go dołączyć --.
    • &jest ogólny, zdefiniowany tak, że x&y=x.
    • %jest zdefiniowany w taki sposób, że [a]%y=aumożliwia zastąpienie !!0i jednoczesne wymuszenie, aby jego argument ciągu miał długość 1.
  • Znak nowej linii stanowi szczególny problem, ponieważ \nwydaje się niemożliwe zmieszczenie się w dosłownym łańcuchu zawierającym tylko 3 bajty w linii.
    • Dlatego łatwiejszą do zdefiniowania c x=["9"%0,"8"%0..]!!xjest konwertowanie z znaku Intna znak, licząc od cyfry w '9'dół.
  • Dlatego show to cztery znaki, wyprowadzanie liczb musi być realizowane ręcznie.
    • dto lista ciągów cyfr "1".."9".
    • nto nieskończona lista reprezentacji liczb ["1","2","3",...]zdefiniowanych rekurencyjnie za pomocą d.
  • #konwertuje Int xdo jego formy applepie podano dodatkowy pierwszy argument, który jest gcdo x15 nowych.

6

Haskell , 7 bajtów / linię, 339 bajtów

Wymóg, aby podział linii był znaczący, sprawia, że ​​jest to nietrywialne wyzwanie w Haskell. Niemal nie ma możliwości wstawienia podziałów linii, których nie można usunąć, więc wszystko musi być zrobione za pomocą legalnie małych instrukcji.

c=cycle
h=head
i=tail
k=[1..]
s=do
 let
  _=0
  _=0
 putStr
t=take
p=print
u=fst
v=snd
z=zip
n=s"\n"
o 5=do
 s"Pie"
 n
o _=n
5%x=o 5
_%x=p x
3!x=do
 s"App"
 s"le"
 o$u x
_!x=do
 let
  y=u x
  z=v x
 y%z
q x=do
 let
  y=u x
  z=v x
 y!z
g[]=s""
g x=do
 q$h x
 g$i x
a=t 3 k
b=t 5 k
l=z$c a
m=z$c b
f n=do
 let
  x=t n
  y=x k
  z=m y
 g$l z

Wypróbuj online!


6

Galaretka , 3 2 bajty / linię, 106 80 56 bajtów

“3
,e
5P
ḍ,
T⁾
ịi
⁾e
AF
ps
,5
⁾¤
pȯ
lµ
,€
⁾Y
”Ỵ
¢Z
¢F
¢v

Wiersze i kolumny literału łańcuchowego zostaną transponowane, więc usunięcie nowych linii zmienia ich kolejność.

Pozostałe linie są oddzielnymi linkami / funkcjami i zawierają wywołania funkcji ( ¢), więc można je połączyć tylko wtedy, gdy wywołania funkcji również zostaną wyeliminowane.

Wypróbuj online!


6

TI-BASIC, 4 bajty na linię

Ponieważ celem jest jedynie zminimalizowanie maksymalnej długości linii, niektóre linie są dłuższe niż powinny, ale najmniejsza, jaką mogłam zrobić, była najdłuższa z 4 bajtów. Dlatego czułem, że ułatwi to odczytanie kodu, jeśli scalę linie, które można połączyć bez przekraczania 4 bajtów.

"APP
Ans→Str1
"LE
Str1+Ans
Ans→Str1
"PIE
Ans→Str2
Input N
1→I
While I≤N
fPart(I/3
not(Ans→A
fPart(I/5
not(Ans→B
If A and B
Then
Str1
Ans+Str2
Disp Ans
Else
If A
Then
Disp Str1
Else
If B
Then
Disp Str2
Else
Disp I
End
End
End
I+1
Ans→I
End

Bez golfa

"APPLE"→Str1
"PIE"→Str2
Input "N:",N
For(I,1,N)
remainder(I,3)=0→A
remainder(I,5)=0→B
If A and B:Then
Disp Str1+Str2
Else
If A:Then
Disp Str1
Else
If B:Then
Disp Str2
Else
Disp I
End
End
End
End

O języku i ograniczeniach

TI-BASIC jest językiem tokenizowanym, aw tym przypadku każdy z tokenów ma 1 bajt, z wyjątkiem StrNzmiennych, które są 2 bajtami. Możesz też zrezygnować z zamykania nawiasów przez większość czasu. remainder(Funkcja 2 bajty, więc stosując to wymagają co najmniej 5 bajtów (jedno dla funkcji, dwa dla argumentów i jeden dla przecinek we remainder(I,3). Zamiast tego użyłem funkcji fPart(i, not(aby go skrócić, które są 1-bajtowymi tokenami. Widać też, że Ansdość często korzystałem z wbudowanej zmiennej , ponieważ każde wyrażenie, które samo jest oceniane w linii, jest automatycznie do niej zapisywane. Mogę więc zaoszczędzić kilka bajtów, dzieląc wyrażenia i przypisania.

Inną strategią było oczywiście zminimalizowanie przypisań ciągów. Moja metoda zrobienia tego zależała od maksymalnej długości linii w pozostałej części kodu. Gdy ustaliłem, że to 4 bajty, byłem w stanie wcisnąć jak najwięcej każdego łańcucha w tym samym wierszu, jak to możliwe, aby zminimalizować liczbę potrzebnych zadań. Zrobiłem to ze względu na czytelność.

Czynnikami ograniczającymi w tym kodzie są przypisania do zmiennych łańcuchowych i konkatenacja ze zmiennymi łańcuchowymi. Linie Ans→Str1i Str1+Ansoba mają łącznie 4 bajty. Musiałbym znaleźć sposób na całkowite wyeliminowanie zmiennych łańcuchowych, aby dodatkowo zminimalizować maksymalną długość linii w moim kodzie. Całą resztę można skrócić do maksymalnie 3 bajtów lub mniej na linię.

Problem leży w przypisaniach do zmiennych numerycznych, takich jak 1→I. Nie możesz dalej grać w golfa bez znalezienia rozwiązania bez zmiennych, które nie przekraczają 2 bajtów długości linii. To zdarza się niemożliwe w przypadku tego wyzwania.

Operatory binarne, takie jak, +wymagają symbolu operatora oraz argumentów lewego i prawego. Bez tego nie byłoby możliwości połączenia łańcuchów. Bez konkatenacji łańcuchów nie byłoby sposobu wyświetlenia łańcuchów wymaganych przez ten program do ukończenia wyzwania bez przekraczania 2 bajtów długości linii. Dlatego teoretyczny limit tego wyzwania w tym języku wynosiłby 3 bajty na linię, czego nie byłem w stanie osiągnąć.


Ale najdłuższa linia w wersji If A and B
golfowej

@jmarkmurphy TI-BASIC jest językiem tokenizowanym, a większość tokenów jest reprezentowana przez jeden bajt. Wspomniałem o tym w moim opisie rozwiązania. Możesz przeczytać więcej na ten temat na tej wiki .
kamoroso94

Ale założeniem było, że redaktorzy powinni dopuszczać minimalną liczbę znaków w wierszu. Wątpię, czy piszesz tokeny za pomocą edytora. I nie sądzę, że którykolwiek z innych języków, które nie są czysto interpretowane, używa skompilowanego obiektu lub tokenizowanej liczby bajtów.
jmarkmurphy

@ jmarkmurphy faktycznie piszesz tokeny w edytorze. AnsToken jest 1 bajt, natomiast trzy kolejne znaki Anssą 1, 2 i 2 bajty odpowiednio w sumie 5. Nie jest to ciąg znaków ASCII, to dosłownie token po wpisaniu go na kalkulatorze.
kamoroso94

W sprawie meta istnieje pewien konsensus .
kamoroso94

6

C (gcc) , 2 bajty na linię, 374 368 320 310 262 bajtów

Zakładam, że można go trochę pograć w golfa. Ukośniki odwrotne poprzedzające nowe linie sprawiają, że jest to trochę banalne.

i\
;\
f\
(\
n\
)\
{\
f\
o\
r\
(\
i\
=\
0\
;\
i\
+\
+\
<\
n\
;\
p\
r\
i\
n\
t\
f\
(\
i\
%\
3\
&\
&\
i\
%\
5\
?\
"\
%\
d\
\\
n\
"\
:\
i\
%\
3\
?\
"\
P\
i\
e\
\\
n\
"\
:\
i\
%\
5\
?\
"\
A\
p\
p\
l\
e\
\\
n\
"\
:\
"\
A\
p\
p\
l\
e\
P\
i\
e\
\\
n\
"\
,\
i\
)\
)\
;\
}

Wypróbuj online!


@ Ørjan Johansen Ah, całkiem słusznie.
gastropner

Możesz usunąć wiele odwrotnych ukośników, zmniejszając swój wynik za remis. Ponadto nie ma potrzeby oddzielania dwubajtowych tokenów, takich jak &&.
Toby Speight,


5

PHP 7, 2 bajty na linię

(#
c#
.#
r#
.#
e#
.#
a#
.#
t#
.#
e#
.#
_#
.#
f#
.#
u#
.#
n#
.#
c#
.#
t#
.#
i#
.#
o#
.#
n#
)#
(#
'#
'#
,#
g#
.#
l#
.#
o#
.#
b#
.#
a#
.#
l#
.#
(#
c#
.#
h#
.#
r#
)#
(#
6#
*#
6#
)#
.#
a#
.#
r#
.#
g#
.#
n#
.#
(#
c#
.#
h#
.#
r#
)#
(#
7#
*#
8#
+#
3#
)#
.#
w#
.#
h#
.#
i#
.#
l#
.#
e#
.#
(#
c#
.#
h#
.#
r#
)#
(#
5#
*#
8#
)#
.#
(#
c#
.#
h#
.#
r#
)#
(#
6#
*#
6#
)#
.#
i#
.#
(#
c#
.#
h#
.#
r#
)#
(#
6#
*#
7#
+#
1#
)#
.#
(#
c#
.#
h#
.#
r#
)#
(#
6#
*#
7#
+#
1#
)#
.#
(#
c#
.#
h#
.#
r#
)#
(#
7#
*#
8#
+#
4#
)#
.#
(#
c#
.#
h#
.#
r#
)#
(#
6#
*#
6#
)#
.#
a#
.#
r#
.#
g#
.#
n#
.#
(#
c#
.#
h#
.#
r#
)#
(#
5#
*#
8#
+#
1#
)#
.#
e#
.#
c#
.#
h#
.#
o#
.#
(#
c#
.#
h#
.#
r#
)#
(#
6#
*#
6#
)#
.#
i#
.#
(#
c#
.#
h#
.#
r#
)#
(#
6#
*#
6#
+#
1#
)#
.#
3#
.#
(#
c#
.#
h#
.#
r#
)#
(#
7#
*#
9#
)#
.#
(#
c#
.#
h#
.#
r#
)#
(#
5#
*#
8#
)#
.#
(#
c#
.#
h#
.#
r#
)#
(#
6#
*#
6#
)#
.#
i#
.#
(#
c#
.#
h#
.#
r#
)#
(#
6#
*#
6#
+#
1#
)#
.#
5#
.#
(#
c#
.#
h#
.#
r#
)#
(#
7#
*#
9#
)#
.#
(#
c#
.#
h#
.#
r#
)#
(#
6#
*#
6#
)#
.#
i#
.#
(#
c#
.#
h#
.#
r#
)#
(#
7#
*#
8#
+#
2#
)#
.#
P#
.#
i#
.#
e#
.#
(#
c#
.#
h#
.#
r#
)#
(#
5#
*#
8#
+#
1#
)#
.#
(#
c#
.#
h#
.#
r#
)#
(#
7#
*#
8#
+#
2#
)#
.#
(#
c#
.#
h#
.#
r#
)#
(#
5#
*#
8#
)#
.#
(#
c#
.#
h#
.#
r#
)#
(#
6#
*#
6#
)#
.#
i#
.#
(#
c#
.#
h#
.#
r#
)#
(#
6#
*#
6#
+#
1#
)#
.#
5#
.#
(#
c#
.#
h#
.#
r#
)#
(#
7#
*#
9#
)#
.#
A#
.#
p#
.#
p#
.#
l#
.#
e#
.#
(#
c#
.#
h#
.#
r#
)#
(#
7#
*#
8#
+#
2#
)#
.#
A#
.#
p#
.#
p#
.#
l#
.#
e#
.#
P#
.#
i#
.#
e#
.#
(#
c#
.#
h#
.#
r#
)#
(#
5#
*#
8#
+#
1#
)#
.#
(#
c#
.#
h#
.#
r#
)#
(#
6#
*#
7#
+#
2#
)#
.#
(#
c#
.#
h#
.#
r#
)#
(#
4#
*#
8#
+#
2#
)#
.#
(#
c#
.#
h#
.#
r#
)#
(#
2#
*#
5#
)#
.#
(#
c#
.#
h#
.#
r#
)#
(#
4#
*#
8#
+#
2#
)#
.#
(#
c#
.#
h#
.#
r#
)#
(#
7#
*#
8#
+#
3#
)#
)#
(#
)#
;#

Jak to działa z kropkami?
L3viathan

@ L3viathan Dots oznaczają konkatenację. Służą do budowania długich ciągów znaków z pojedynczych znaków.
user63956

Wiem o tym, ale czy PHP po prostu tworzy ciągi znaków z nieprzypisanych nazw zmiennych lub jak to działa? Nie widzę znaków cytowania.
L3viathan

2
@ L3viathan Te postacie są stałymi. Jeśli stała nie została zdefiniowana, PHP używa swojej nazwy jako wartości.
user63956

5

Aceto , 1 bajt na linię, 230 bajtów

Cóż, pisanie nie było fajne. Jako fungoid struktury kontrolne Aceto w dużej mierze polegają na swojej naturze 2D, ale możemy to obejść za pomocą wielu, wielu warunkowych ucieczek (` ). Jedynym problemem jest to, że wpływają one na następne polecenie, niezależnie od jego obecności (wszystkie programy Aceto są wewnętrznie kwadratami), dlatego musimy wyrównać program w niektórych miejscach, wstawiając puste linie w niektórych punktach.

Literałów łańcuchowych tak naprawdę nie można używać, ale literałów char można (w niektórych miejscach; znowu musimy je wyrównać).

&
p
$
L
Q
`
L
p
`
L
d
`
L
Q
`
L
Q
`
L
x
`

L
M
!
%
5
d
$
L
Q
`
L
Q
`
L
p
`
L
d
`
L
Q
`
L
x
`
L
M
!
%
3
d
$
L
p
`
L
d
`
L
x
`

L
M
!
%
*
5
3
d
[
X
`

n
=
0
l
)
@
(
z
i
r
{
J
s
]
d
s
}
d
[
~
£
A
'
d
p
'

l
'

e
'

{
~
£
P
'

i
'
e
'

Wywoływany za pomocą 20:

1
2
Apple
4
Pie
Apple
7
8
Apple
Pie
11
Apple
13
14
ApplePie
16
17
Apple
19
Pie

Wszystkie podziały linii muszą mieć znaczenie. Podziały linii, które można usunąć, i sąsiadujące linie połączone bez wpływu na wynik, muszą zostać usunięte.

Tak się nigdy nie dzieje, ponieważ biegnie od dołu do góry.

Jest co najmniej jedno miejsce, w którym możemy zaoszczędzić 2 bajty (zamieniając na `Xa |lub #), ale zachowałem ją taką, jaka jest, ze względu na koszty wykonania związane z przejściem przez stosunkowo dużą krzywą Hilberta.

Zignorowałem także dorozumiany wymóg używania \rlub \r\nnowego wiersza, ponieważ uważam, że jest to niezamierzony błąd OP. Jeśli istnieje zmiana lub komentarz wzmacniający ten wymóg, mogę go zmienić bez większego problemu, aby zamiast tego użyć nowego wiersza CR.

Liczba bajtów jest oparta na kodowaniu kodowania golfowego Aceto; Latin-7, w której £jest jeden bajt.


Re Zakładając, że trzy łańcuchy na stosie […] i To zastąpienie pozostawia się jako ćwiczenie dla czytelnika. : Proszę podać pełny kod wymagany do rozwiązania danego zadania. Twoje rozwiązanie jest niekompletne. Brakuje również liczby bajtów, która jest rozstrzygaczem dla rozwiązań z wynikiem 1.
Dennis

@Dennis Zredagowałem odpowiedź, aby podać pełny działający kod.
L3viathan

5

Perl 5 , 2 bajty na linię, 182 bajty

&
#
{'
Er
0h
|R
hR
o
'#
^#
'I
 O
Ro
3f
+~
'#
.#
(#
p#
|#
Y#
)#
}#
(#
'z
;d
y"
"z
7#
vU
aW
zZ
7#
vU
gW
..
~.
4e
r;
|6
'#
^#
('
xR
~R
KR
fR
QR
/R
$R
cR
QR
/R
vR
UR
%R
xR
$R
'#
.#
4#
))

Wypróbuj online!

Składnia Perla jest bardzo wybaczająca, więc można dodać wiele luk do kodu i dodanych komentarzy, co sprawia, że ​​podstawowa idea jest dość prosta. Głównym celem tego kodu jest zbudowanie ciągu zawierającego kod, który chcemy uruchomić, ieval to. W Perlu możliwe jest wywołanie funkcji za pomocą ciągu znaków lub zmiennej z &{...}zapisem, niestety nie evaljest to możliwe w tej formie, ale evalbytestak długo, jak długo wywołujesz ją przez CORE::przestrzeń nazw. Budowanie tego ciągu było dość proste, a program jest przekazywany bezpośrednio do tego wywołania. Ciągi są budowane przy użyciu nowych wierszy jako części XOR, aby je zbudować , użyłem tego skryptu. Aby zachować to ważność, w kilku miejscach musiały być umieszczone komentarze, aby usunięcie nowej linii spowodowało brak działania kodu.

Procedura FizzBuzz została zaczerpnięta z doskonałej odpowiedzi primo .


Perl 5 , 1 bajt na linię, 172 bajty

Tak więc (teraz) wiem, że jest to nieprawidłowe , ponieważ kilka nowych linii można usunąć, ale ponieważ było to moje oryginalne podejście do problemu, dodam go. Fajnie było zobaczyć, jak daleko można przesunąć składnię Perla! Podobał mi się ten problem sam w sobie, mimo że jest nieważny.

&
{
(
I
.
'
X
0
o
k
h
~
'
.
(
p
|
Y
)
)
^
'
E
O
0
|
f
s
o
'
}
(
'
x
d
!
K
z
o
Q
U
9
$
Z
o
Q
U
?
v
.
&
%
e
*
$
6
'
^
'

c
~
"
z
f
#
.
/
W
"
c
#
.
/
W
v
U
.
l
x
;
$
4
'
^
p
)

Wypróbuj online!


Czy to nie łamie zasady „Wszystkie podziały linii muszą mieć znaczenie”?
maja

@ 12Me21 tak, właśnie na to patrzyłem. Więc pierwszy zepsuje go, jeśli zostanie usunięty, ale niektóre z pozostałych rzeczywiście można usunąć, ustawiając to na długość 2. Cholera, spędziłem wieki na podejściu, które działało z jednym char na linię!
Dom Hastings,

@ 12Me21 Myślę , że mam rozwiązanie, które działa teraz dla 2, dodałem golfową wersję 1-bajtowej długości, odkąd spędziłem czas, aby to zrobić, cholerne zasady! :)
Dom Hastings

5

SmileBASIC, 9 7 bajtów na linię, 159 155 154 152 bajtów

To było naprawdę zabawne wyzwanie. Niestety, zasada niepotrzebnych podziałów linii powoduje kilka problemów (choć na szczęście nie wpływa to tutaj na maksymalną długość linii). Musiałem dodać komentarze między liniami jak A%=I/3i A=A%*3, ponieważ A%=I/3A=A%*3w SB jest poprawnie analizowane. I był w stanie wykorzystać trick opuścić kilka uwag, ponieważ zastąpienie Az Emarek, które nieważne linia (To ma coś wspólnego z liczb zapisanych za pomocą Enotacji, myślę. 3EJest uważany za nieprawidłowy numer, a nie numer i nazwę zmiennej).

A$="App
B$="le
P$="Pie
INPUT N
R=N
WHILE R
INC I
R=I<N
A%=I/3'
A=A%*3'
A=A==I
B%=I/5
E=B%*5
E=E==I'
?A$*A;
?B$*E;
?P$*E;
C=A+E
WHILE!C
C=1?I;
WEND?
WEND

Największym ograniczeniem jest tutaj wkład. INPUT xjest najprostszym dozwolonym sposobem, alternatywnie jest zdefiniowanie funkcji o wartości wejściowej takiej jak, DEF F xale to wciąż 7 znaków. Trudne jest także wyrażenie warunkowe; Nie mogę wymyślić nic krótszego niż WHILE x.


1
Jeśli A%=I/3A=A%*3jest poprawny składniowo, ale logicznie uszkodzony, nie potrzebujesz znaku komentarza.
Nick T

Jest poprawnie parsowany jako A%=I/3i A=A%*3, więc komentarz jest wymagany.
maja

3

JavaScript (ES6), 3 bajty na linię

Używa zmiennej globalnej, topaby uzyskać dostęp do windowobiektu, z którego otrzymujemy evalnastępujący kod:

n=prompt('')
i=0
for(;++i<=n;console.log(i%5?f||i:f+'Pie'))f=i%3?'':'Apple'

Będziesz musiał uruchomić go w konsoli, ponieważ topjest niedostępny z piaskownicowego fragmentu stosu.


t//
=//
top
t//
[`\
ev\
al\
`//
]//
(`\
n=\
pr\
om\
pt\
('\
')
i=0
fo\
r(\
;+\
+i\
<=\
n;\
co\
ns\
ol\
e.\
lo\
g(\
i%\
5?\
f|\
|i\
:f\
+'\
Pi\
e'\
))\
f=\
i%\
3?\
''\
:'\
Ap\
pl\
e'\
`)

3

C #, 9 bajtów na linię, 248 242 230 bajtów

Ponieważ C # nie przejmuje się łamaniem linii, potrzebuje komentarza online na końcu prawie (dzięki Ørjan Johansen) każdej linii, aby zachować zgodność z regułami. Ten program oczekuje n jako argumentu wiersza poleceń. Oto możliwie jak najwięcej nowych linii, których nie można usunąć:

class
A//
{//
static
void
Main//
(//
string//
[//
]//
a//
)//
{//
for//
(//
var
i//
=//
0//
;//
i++//
<//
int//
.Parse//
(//
a//
[//
0//
]//
)//
;//
)//
{//
var
s//
=//
""//
;//
if//
(//
i//
%//
3//
==//
0//
)//
s//
+=//
"A"+//
"p"+//
"p"+//
"l"+//
"e"//
;//
if//
(//
i//
%//
5//
==//
0//
)//
s//
+=//
"P"+//
"i"+//
"e"//
;//
if//
(//
s//
==//
""//
)//
s//
=//
$"{i}"//
;//
System//
.//
Console//
.//
Write//
(//
s//
+//
@"
"//
)//
;//
}//
}//
}

Ale ponieważ najdłuższa linia ma 9 bajtów, inne linie również mogą uzyskać taką długość, goląc niektóre bajty:

class
A{static
void
Main(//
string[//
]a){//
for(var
i=0;i++//
<int.//
Parse(a//
[0]);){//
var 
s="";if//
(i%3==0//
)s+=//
"Apple"//
;if(i%5//
==0)s+=//
"Pie";//
if(s==//
"")s=//
$"{i}";//
System.//
Console//
.Write(//
s+@"
");}}}

Zinterpretowałem konkatenację jako „bez spacji między”, więc nie potrzebujesz //między tokenami, które połączyłyby się, jak statici void.
Ørjan Johansen

@ ØrjanJohansen Thanks! Zapisano 6 bajtów
Arthur Rump

Myślę, że możesz zaoszczędzić więcej bajtów, przestawiając je na var s="";if// (i%3==0// )s+=// "Apple"// ;if(i%5//.
Ørjan Johansen

I jest podobna możliwość przejścia Az pierwszej do drugiej linii.
Ørjan Johansen

Zapisano także 3 bajty, zmieniając „\ n” na @ ””, z drugim cudzysłowem w nowym wierszu, co również wymagało wprowadzenia nowego wiersza.
Arthur Rump

2

Python 2, 5 bajtów / linię, 93 bajty

Standard max6 jest już przestarzały.

def\
f(n):
 i=0
 \
exec\
'pri\
nt i\
%3/2\
*"Ap\
ple"\
+i%5\
/4*"\
Pie"\
or-~\
i;i+\
=1;'\
*n

Wypróbuj online!

Python 2 i 3, 5 bajtów / linię, 100 bajtów

def\
f(n):
 i=0
 \
exec\
('pr\
int(\
i%3/\
/2*"\
Appl\
e"+i\
%5//\
4*"P\
ie"o\
r-~i\
);i+\
=1;'\
*n)

Wypróbuj online!


2

JavaScript, maksymalnie 6 bajtów / wiersz, 528 bajtów

Pomysł zgarnął stąd .

Kod został zgrany stąd .

Podziękowania dla Andersa Kaseorga za g=evaloszczędność bajtu na linię.

a="n"
a+="="
a+="p"
a+="r"
a+="o"
a+="m"
a+="p"
a+="t"
a+="("
a+="'"
a+="'"
a+=")"
a+=";"
a+="f"
a+="o"
a+="r"
a+="("
a+="i"
a+="="
a+="0"
a+=";"
a+="+"
a+="+"
a+="i"
a+="<"
a+="="
a+="n"
a+=";"
a+="c"
a+="o"
a+="n"
a+="s"
a+="o"
a+="l"
a+="e"
a+="."
a+="l"
a+="o"
a+="g"
a+="("
a+="i"
a+="%"
a+="5"
a+="?"
a+="f"
a+="|"
a+="|"
a+="i"
a+=":"
a+="f"
a+="+"
a+="'"
a+="P"
a+="i"
a+="e"
a+="'"
a+=")"
a+=")"
a+="f"
a+="="
a+="i"
a+="%"
a+="3"
a+="?"
a+="'"
a+="'"
a+=":"
a+="'"
a+="A"
a+="p"
a+="p"
a+="l"
a+="e"
a+="'"
g=eval
g(a)

Niesperowane:

n=prompt('');for(i=0;++i<=n;console.log(i%5?f||i:f+'Pie'))f=i%3?'':'Apple'

a=""+\n"f"+\n"o"+ ...a zakończenie eval(\na)jest nieco krótsze
Value Ink

Reguły nieco się zmieniły (ApplePie, weź dane wejściowe), ale twój schemat powinien być nadal aktualny.
Nick T

Zmiana reguły unieważnia sugestię @ ValueInk, ale nadal możesz zakończyć się na f=evali f(a).
Anders Kaseorg

@AndersKaseorg dziękuję :) nie pomyślałem o tym
Stephen

1
Możesz zapisać bajt, umieszczając 2 znaki w ciągu w pierwszym wierszu.
12Me21

2

PHP, 4 bajty / linia

for#
(#
$z=#
${#
ar.#
gn#
};#
$k#
++<#
$z#
;){#
(#
pr.#
in.#
t_.#
r)#
([#
A.#
p.p#
.le#
][#
$k#
%3#
].[#
Pie#
][#
$k#
%5#
]?:#
$k)#
;(#
pr.#
in.#
t_.#
r)#
("
");}

Wypróbuj online!


Wszystkie podziały linii muszą mieć znaczenie. Podziały linii, które można usunąć, i sąsiadujące linie połączone bez wpływu na wynik, muszą zostać usunięte.
Julian Wolf

@JulianWolf Mam to zmienić
Jörg Hülsermann

2

APL (Dyalog) , 5 bajtów na linię

f
A'A'
p'p'
p,←p
e'e'
A,←p
l'l'
A,←l
A,←e
P'P'
i'i'
P,←i
P,←e
{O''
M3|⍵
M0=M
OM/A
M5|⍵
M0=M
MM/P
O,←M
M←⍴O
M0=M
MM/⍵
O,←M
⎕←O
}¨⍳⎕

Wypróbuj online!


2

Siatkówka , 4 bajty / linię

.+
$*      Convert the input number to unary.
1
$`1¶    Count from 1 to the input number.
111
A       Divide by 3.
+`A1
1111    If there was a remainder, restore the original number.
A{5}
AP      If the number is divisible by 3, try to divide by 5. 
.*A     The result ends in `AP` if the number is divisible by 15,
Appl    or in `A` if it is only divisible by 3. Replace everything
l       up to the `A` with `Apple`; multiples of 15 become `AppleP`.
le
1{5}    If the number did not divide by 3, try dividing it by 5 anyway.
P
+`P1    If there was a remainder, restore the original number.
6$*1    Otherwise replace the result with `Pie`,
P+      which also fixes multiples of 15.
Pie     If the number was divisible by neither 3 nor 5,
1+      convert it back to decimal.
$.&

Wypróbuj online!


2

R , 10 bajtów na linię, 800 bajtów

Reguła „znaczących przełamań linii” stanowiła wyzwanie. Obecnie to przeliteruje kod fizzbuzz na ciąg znaków, a następnie wykonuje go.

a="x"
a[2]="="
a[3]="y"
a[4]="="
a[5]="1"
a[6]=":"
a[7]="s"
a[8]="c"
a[9]="a"
a[10]="n"
a[11]="("
a[12]=")"
a[13]=";"
a[14]="y"
a[15]="["
a[16]="3"
a[17]="*"
a[18]="x"
a[19]="]"
a[20]="="
a[21]="'"
a[22]="A"
a[23]="p"
a[24]="p"
a[25]="l"
a[26]="e"
a[27]="'"
a[28]=";"
a[29]="y"
a[30]="["
a[31]="5"
a[32]="*"
a[33]="x"
a[34]="]"
a[35]="="
a[36]="'"
a[37]="P"
a[38]="i"
a[39]="e"
a[40]="'"
a[41]=";"
a[42]="y"
a[43]="["
a[44]="1"
a[45]="5"
a[46]="*"
a[47]="x"
a[48]="]"
a[49]="="
a[50]="'"
a[51]="A"
a[52]="p"
a[53]="p"
a[54]="l"
a[55]="e"
a[56]="P"
a[57]="i"
a[58]="e"
a[59]="'"
a[60]=";"
a[61]="w"
a[62]="r"
a[63]="i"
a[64]="t"
a[65]="e"
a[66]="("
a[67]="y"
a[68]="["
a[69]="x"
a[70]="]"
a[71]=","
a[72]="'"
a[73]="'"
a[74]=")"
t=toString
g=gsub
o=", "
l=""
f=t(a)
r=g(o,l,f)
P=parse
p=P(t=r)
eval(p)

Wypróbuj online!

Oto łączone kod applepie (zaadaptowane z MickyT w golfa tutaj ).

x=y=1:scan()
y[3*x]='Apple'
y[5*x]='Pie'
y[15*x]='ApplePie'
write(y[x],'')

I niepoznana wersja kodu parsującego:

eval(t=parse(gsub(", ", "", toString(a))))

Tutaj używam toStringdo łączenia listy symboli aw pojedynczy ciąg. Jednak domyślnym zachowaniem jest oddzielenie każdego symbolu ,, więc wywołujemy, gsubaby zastąpić je zerami. Następnie przekazujemy toparse ieval wykonujemy brudną robotę.

Jest możliwe, że jest to podejście, które nie korzysta z tej metody ciąg parsowanie i tylko prosto narzędzi fizzbuzz, ale wydaje mi się, że za pomocą forlub whilelub definiowania functionpotrzeb dłuższe niż linie obecnego podejścia.


2

Rubinowy, 105 bajtów / linię, 354 214 bajtów

-140 bajtów z surowego wyniku @NieDzejkob.

eval\
"pu"\
"ts"\
" ("\
"1."\
".g"\
"et"\
"s."\
"to"\
"_i"\
")."\
"ma"\
"p{"\
"|i"\
"|i"\
"%1"\
"5<"\
"1?"\
":A"\
"pp"\
"le"\
"Pi"\
"e:"\
"i%"\
"5<"\
"1?"\
":P"\
"ie"\
":i"\
"%3"\
"<1"\
"?:"\
"Ap"\
"pl"\
"e:"\
"i}"

Jak to działa

Ruby automatycznie połączy sekwencje literałów łańcuchowych (z wyjątkiem literałów jednoznakowych, takich jak ?a) w tej samej instrukcji. Oznacza to, że x = "a" 'b' "c" %q{d}jest to równoważne z x = "abcd". Używamy tego, aby podzielić kod podobny do FizzBuzz na znacznie mniejsze ciągi do wywoływania eval, ponieważ +spowoduje to unieważnienie programu z powodu reguły remove-newlines, ale \spowoduje błędy składniowe, jeśli nowe linie zostaną usunięte!


Właśnie miałem przesłać coś podobnego
dkudriavtsev

Reguły nieco się zmieniły („ApplePie, weź dane wejściowe), ale twój schemat powinien być nadal aktualny.
Nick T

Możesz zaoszczędzić wiele bajtów, dodając dwa znaki do łańcucha w każdej linii.
NieDzejkob,

@NieDzejkob głównym mechanizmem oceniania jest tutaj liczba bajtów na linię, co oznacza, że ​​lepiej poświęcić całkowitą liczbę bajtów, aby zmniejszyć długość linii.
Wartość tuszu

@NieDzejkob nvm Rozumiem, co masz na myśli teraz, ponieważ początkowa evallinia jest dłuższa niż reszta, prawda?
Wartość tuszu

1

Julia 0.6 , 5 bajtów na linię, łącznie 168 bajtów

f=#
n->#
((i,#
a=#
"A"*#
"p"*#
"p"*#
"l"*#
"e",#
p=#
"P"*#
"i"*#
"e"#
)->#
["$i
","$a
","$p
",a*#
p*"
"][#
1+(i#
%3<1#
)+2(#
i%5<#
1)]#
|>[#
print
sin#
][1]#
).(#
1:n)

Wypróbuj online!

The print to nieuchronnie (afaict) do 5 bajtów na terytorium linii.

Nie golfowany:

function f_ungolfed(n)
  inner = (i,
           a="Apple",
           p="Pie") -> ["$i\n",
                        "$a\n",
                        "$p\n",
                        a*p*"\n"][
                                    1 + (i%3 < 1) + 2(i%5 < 1)
                                   ] |> [print; sin][1]
  inner.(1:n)
end

*jest operatorem łączenia łańcuchów, więc a*p*"\n"tworzy „ApplePie \ n”. |>jest operatorem łączenia łańcuchów (/ piping), więc wybrany ciąg zostaje wysłany jako argument do print. Nie sinjest używany, po prostu istnieje, ponieważ printmusi znajdować się w tablicy, aby mieć po nim znaczną spację (użycie #lewy po tym spowoduje zwiększenie liczby bajtów na linię do 6).


Jeśli dozwolone jest po prostu zwracanie danych wyjściowych jako tablicy, można to zrobić z maksymalnie 4 bajtami na linię:

Julia 0.6 , 4 bajty na linię, łącznie 152 bajty

f=#
n->#
((i#
,a=#
"A"#
*#
"p"#
*#
"p"#
*#
"l"#
*#
"e"#
,p=#
"P"#
*#
"i"#
*#
"e"#
)->#
[i,#
a,p#
,a*#
p][#
1+(#
i%3#
<1#
)+#
2(i#
%5<#
1)]#
).(#
1:n#
)

Wypróbuj online!

Funkcja, która pobiera n i zwraca tablicę zawierającą oczekiwane dane wyjściowe. Maksymalna długość linii tutaj jest ograniczona przezn-> - Julia potrzebuje tego w jednym wierszu, aby poprawnie parsować go jako początek lambda.


1

Pascal (FPC) -Sew , 6 bajtów na linię, 348 320 bajtów

var
n,i://
word//
;begin
read//
(n);//
for
i:=1to
n do
if 0=i
mod
15then
write{
$}(//
'A',//
'p',//
'p',//
'l',//
'e',//
'P',//
'i',//
'e',//
#10)//
else
if 0=i
mod
3then
write{
$}(//
'A',//
'p',//
'p',//
'l',//
'e',//
#10)//
else
if 0=i
mod
5then
write{
$}(//
'P',//
'i',//
'e',//
#10)//
else
write{
$}(i//
,#10//
)end.

Wypróbuj online!

Wykorzystuje FPC, aby uzyskać 6 bajtów na linię; bez tego wynik byłby znacznie gorszy. Jest to najmniejsza możliwa szerokość linii, ponieważ po writemusi być albo ;albo ((albo niepotrzebne białe znaki), więc wstawiono specjalny komentarz, aby tego uniknąć. Funkcje FPC, które wpłynęły na tę odpowiedź, to:

  1. // - rozpoczynanie komentarzy w jednym wierszu.
  2. Blokowane komentarze w formie {$<something>...}są dyrektywami kompilatora. Jeśli dyrektywa nie istnieje, FPC wyda ostrzeżenie (i {$ ...}tak dalej). W tym programie{ i $są oddzielone znakiem nowej linii, która wyświetli ostrzeżenie po usunięciu.
  3. -Sew- Kompilator zatrzymuje się także po ostrzeżeniach {i $dołączył do zatrzymania kompilacji.

1

Japt , 3 bajty na linię

Prawie udało się sprowadzić go do dwóch bajtów na linię, ale powrót z mapy psuje się, jeśli następuje po niej nowa linia.
Sama implementacja FizzBuzz pochodzi z kanonicznego wątku FizzBuzz .


`A
p
p
l
e
`y
Vx
`P
i
e
`y
Xx
ò1\
 Ë\
;W\
pD\
v3\
)+\
Yp\
Dv\
5)\
ªD\
÷

Wypróbuj online!


1

LOLCODE , 18 8 bajtów na linię, łącznie 303 bajty

HAI 1.2
I HAS A…
B ITZ 0
IM IN…
YR L
B R SUM…
OF B AN…
1
MOD OF…
B AN 15
WTF?
OMG 0
VISIBLE…
"Apple"…
"Pie"
OMGWTF
MOD OF…
B AN 5
WTF?
OMG 0
VISIBLE…
"Pie"
OMGWTF
MOD OF…
B AN 3
WTF?
OMG 0
VISIBLE…
"Apple"
OMGWTF
VISIBLE…
B
OIC
OIC
OIC
BOTH…
SAEM B…
AN 100
O RLY?
YA RLY
GTFO
OIC
IM…
OUTTA…
YR L
KTHXBYE

Wypróbuj online!

-10 bajtów na linię za pomocą znaku kontynuacji linii , dzięki Ørjan Johansen!


Możesz zmniejszyć to do 8 za pomocą… znaku kontynuacji linii. Wypróbuj online!
Ørjan Johansen

Codziennie uczę się czegoś nowego o tych esolangach. Dzięki, Oerjan!
JosiahRyanW

0

Python 2 , 5 bajtów / linię

exec\
'f\
o\
r\
 \
x\
 \
i\
n\
 \
x\
r\
a\
n\
g\
e\
(\
1\
,\
i\
n\
p\
u\
t\
(\
)\
+\
1\
)\
:\
\n\
 \
i\
f\
 \
x\
%\
1\
5\
=\
=\
0\
:\
s\
="\
A\
p\
p\
l\
e\
P\
i\
e"\
\n\
 \
e\
l\
i\
f\
 \
x\
%\
5\
=\
=\
0\
:\
s\
="\
P\
i\
e"\
\n\
 \
e\
l\
i\
f\
 \
x\
%\
3\
=\
=\
0\
:\
s\
="\
A\
p\
p\
l\
e"\
\n\
 \
e\
l\
s\
e\
:\
s\
=\
x\
\n\
 \
p\
r\
i\
n\
t\
(\
s\
)'

Wypróbuj online!


Ostrożny! 'z\"'oznacza to samo co 'z\"', więc redundantna reguła nowej linii oznacza, że ​​nie możesz rozpocząć linii kontynuacji wewnątrz ciągu ".
Anders Kaseorg

@AndersKaseorg robione to r'...'teraz
Martmists

To rzuca a SyntaxError.
Erik the Outgolfer

TIO zatrzymuje jeden numer wcześniej. Ponadto zasady uległy zmianie z używania FizzBuzzna używanie ApplePie.
Ørjan Johansen

0

JavaScript (ECMAScript6), 2 bajty na linię

'\
'[
'\
b\
i\
g'
][
'\
c\
o\
n\
s\
t\
r\
u\
c\
t\
o\
r'
][
'\
c\
a\
l\
l'
](
0,
`\
n\
=\
p\
r\
o\
m\
p\
t\
(\
'\
'\
)\
;\
i\
=\
0\
;\
f\
o\
r\
(\
;\
+\
+\
i\
<\
=\
n\
;\
c\
o\
n\
s\
o\
l\
e\
.\
l\
o\
g\
(\
i\
%\
5\
?\
f\
|\
|\
i\
:\
f\
+\
'\
P\
i\
e\
'\
)\
)\
f\
=\
i\
%\
3\
?\
'\
'\
:\
'\
A\
p\
p\
l\
e\
'\
`)
()


Długie wyjaśnienie

Sposób, w jaki możemy skrócić linie, polega na przekształceniu kodu w łańcuch i ucieczce od końca linii, co spowoduje ograniczenie 2 bajtów na linię.

Tak się alert(1)staje

"\
a\
l\
e\
r\
(\
1\
)"

Ale teraz twój kod jest ciągiem, więc musimy go wykonać jako kod. Znam co najmniej 4 sposoby wykonywania łańcucha jako kodu:

  1. eval (kod) . Do wywołania potrzeba co najmniej 5 bajtóweval(
  2. setTimeout (kod, limit czasu) . Uruchamia funkcję asynchronicznie, ale opcjonalnie, jeśli przekażesz ciąg, wywoła eval wewnętrznie.
  3. Możesz skorzystać z DOM i wstawić kod do onclick=""atrybutu, ale nie udało mi się skrócić tworzenia elementu.
  4. Wywołanie konstruktora funkcji new Function () parsuje twój kod w anonimową funkcję, którą możesz wywołać później (użyłem tego).

Wszystkie natywne funkcje mieszka wewnątrz okna obiektu w javascript i można uzyskać dostęp do właściwości obiektu za pomocą notacji kropki więc eval()staje się window.eval(), czy można uzyskać dostęp do właściwości za pomocą notacji nawiasu window['eval']() . Możesz skorzystać z tego, aby rozbić evalwiele linii przy użyciu metody opisanej wcześniej. Ale nadal musisz wpisać okno , jedną sztuczką jest to, że jeśli nie znajdujesz się w ramce, górną zmienną jest również okno, więc window.eval staje się top.eval (3 bajty mniej).

w=top
w['eval']

You can shorten the assignment using parenthesis
w=(
top
)
w[
'e\
av\
al'
](
/*string*/
)

Czyni to kod minimum 3 bajtów. Aby utworzyć 2 bajty kodu, użyłem new Function(/*string*/);konstruktora, ale musiałem być kreatywny, aby uzyskać do niego dostęp bez konieczności wpisywania go.

Po pierwsze, konstruktor funkcji umożliwia wywołanie go jako funkcji pomijającej nowe słowo kluczowe, co zmniejsza 4 bajty, ale jest również ważne z innego powodu. Wywołanie konstruktora jako funkcja nadal zwraca instancję To pozwala nam włączyć new Function(code)doFunction(code) . Inną ważną rzeczą jest to, że konstruktor funkcji ma callmetodę, która pozwala wywoływać dowolną funkcję, ale zastępuje to odwołanie, a sam konstruktor funkcji jest funkcją, którą można wywołać na niejFunction.call(null, code) .

Wszystkie funkcje rodzime są instancjami konstruktora funkcji, a wszystkie obiekty w javascript mają właściwość konstruktora . Możesz więc mieć dostęp do konstruktora funkcji do dowolnej funkcji natywnej alert.constructor, a za pomocą metody wywołania możemy wykonać konstruktor jako funkcję. Teraz mamy alert.constructor.call (null, kod) zwraca funkcję.

łącząc poprzednie thechiniques możemy to zmienić alert['constructor']['call'](null, code)

Teraz musimy tylko znaleźć krótką nazwaną funkcję lub metodę, więc wybieram metodę big () wewnątrz konstruktora String. Więc mogę uzyskać do niego bezpośredni dostęp z pustego ciągu"".big

"".big.constructor.call(null, "code")();
''['big']['constructor']['call'](0,'/* code */')() 

Potem po prostu wszystko zepsułem na 2 bajty

Krótki er wyjaśnienie (TLDR)

Uzyskuję dostęp do nowego konstruktora funkcji (kod), aby przeanalizować ciąg zamiast eval (kod) . Ten konstruktor jest dostępny dla każdej funkcji natywnej poprzez wykonanie dowolnej funkcji. konstruktor , jak alert.constructor===Function. Używam funkcji / metody wewnątrz String.prototype.big String.prototype.big.constructor.call(null, /*string*/) Ale dostęp do niej bezpośrednio z literału ciągu "".bigi zamieniłem go na notację w nawiasie . ""['big']['constructor']['call'](0, CODE)aby móc go złamać za pomocą \.


1
Niestety, myślę, że to jest nieważne, ponieważ np dowolny podział wiersza między 'i ]mogą być usunięte, a program będzie nadal działać poprawnie.
darrylyeo

Nie mogę wymyślić żadnego sposobu na obejście tego, biorąc pod uwagę szerokość 2. Ale ponieważ mamy prawie identyczne podejście , być może możesz dodać dostosowaną wersję swojego wyjaśnienia do mojej odpowiedzi, więc nie wszystko jest stracone?
darrylyeo

0

Pip , 3 bajty na linię, łącznie 72 bajty

V@Y
YUW
Y"L
a
P
S
T
[
`
A
p
p
l
e
`
`
P
i
e
`
]
X
!
*
+
+
i
%
^
3
5
|
i"

Wypróbuj online!

Pip jest wyjątkowo elastyczny pod względem białych znaków, więc jedyną strategią, która wydaje się wykonalna, jest utworzenie łańcucha, zmodyfikowanie go w taki sposób, aby nie zachodziło zakłócenie nowego wiersza, i jego ewaluacja.

Tworzymy ciąg znaków, w którym co drugi znak jest znakiem nowej linii, i bierzemy każdy inny znak za pomocą UW(rozplątuj) i unarnego @(uzyskaj pierwszy element):

UW"abcdef"  => ["ace" "bdf"]
@UW"abcdef" => "ace"

Wynikiem @UWpowinien być nasz kod ApplePie, zaadaptowany z rozwiązania FizzBuzz tutaj . Usunięcie nowych wierszy w ciągu nie spowoduje pełnego kodu, co spowoduje błąd składniowy lub niepoprawne wyjście.

Są jeszcze dwie nowe linie poza ciągiem. Uczyniliśmy to obowiązkowym za pomocą Yoperatora (yank) - który tutaj działa jako zakaz - wraz ze sposobem, w jaki Pip analizuje przebiegi wielkich liter:

YUW   => Y UW
YUW Y => Y UW Y
YUWY  => YU WY

Więc jeśli te nowe wiersze zostaną usunięte, program parsuje inaczej i nie robi tego, co powinien.


0

Java 8, 7 bajtów na linię, 171 bajtów

Pusta lambda bierze int. Podejrzewam, że spełnia to wymóg dotyczący nowych linii, ale nie mogę tego udowodnić, a weryfikacja go brutalną siłą zajęłaby na moim komputerze około miesiąca. Tak to idzie.

a->{//
System
s=//
null;//
for(int
i=0;i//
<a;)s//
.out.//
print//
((++i//
%3*(i//
%5)<1//
?(i%3//
<1?//
"App"//
+"le"//
:"")+//
(i%5<//
1?//
"Pie"//
:"")://
i)+//
"\n");}

Wypróbuj online

Dość nudne ze względu na komentarze do linii. Jedyną interesującą rzeczą jest tutaj użycie zerowego Systemodniesienia, które wydaje się być konieczne, aby wydrukować do standardu w mniej niż 8 bajtów na linię. Zauważ też, że printwywołanie metody jest wąskim gardłem.

Ungolfed bez komentarzy:

a -> {
    System s = null;
    for (int i = 0; i < a; )
        s.out.print(
            (++i % 3 * (i % 5) < 1 ?
                (i % 3 < 1 ? "App"+"le" : "")
                    + (i % 5 < 1 ? "Pie" : "")
                : i
            ) + "\n"
        );
}
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.