23
\$\begingroup\$

Recently, someone proposed more stringent limits for Python's default line length:

Clearly, no program should ever use more than 80 characters per line, for a whole host of reasons. First and foremost, for readability and maintainability, it is important to have a solid standard, so we can adjust the width of our text editors appropriately. As a secondary benefit, code can easily be transferred onto media that may have restrictions, and where adding line-breaks can be distracting, like print pages for review in a meeting, or punch cards.

But is 80 characters too high? Some suggest 79, or even as low as 75, to allow for an 80 character wide terminal to fit the code with a few columns devoted to line numbers. Clearly, ultimately, lower is better, as lower limits allow for the code to be used in more situations without reformatting.

Introducing the max6 standard

Your goal is to find and demonstrate the minimum line length required by Your Favorite Language by writing a FizzBuzz variant with the fewest number of characters in any line.

Input

An integer, n, via any desired method.

Output

Print the numbers from 1 to n, (n ≥ 1, n ∈ ℤ) separated by line breaks, except:

  • for multiples of 3 print "Apple"
  • for multiples of 5 print "Pie"
  • for multiples of both 3 and 5 print "ApplePie"

Scoring

The maximum line length in bytes, not including the line break (Cr, CrLf, Lf, or other system standard break, specify, as desired), and the total code length in bytes as a tiebreaker.

Rules

All line breaks must be meaningful. Line breaks that can be removed and adjacent lines directly concatenated without an impact on the output, must be removed.

\$\endgroup\$
13
  • 2
    \$\begingroup\$ On the newline restriction, if removing a specific group of newlines causes it to work but removing any single newline causes it to fail, must the newlines be removed? They are syntactically important is just that removing some of them cancels out their importance. \$\endgroup\$
    – Wheat Wizard
    Jun 2, 2017 at 22:56
  • 3
    \$\begingroup\$ Not sure how I feel about the "meaningful" newlines rule. When it comes to legal syntax, a wide majority of programming languages don't care about newlines and will let you write the entire program on a single line - just take a look at most of the code-golf solutions here :-P \$\endgroup\$
    – nderscore
    Jun 2, 2017 at 23:37
  • 1
    \$\begingroup\$ Why change it to Apple Pie instead of the standard \$\endgroup\$ Jun 3, 2017 at 2:21
  • 5
    \$\begingroup\$ @RohanJhunjhunwala To prevent using builtin FizzBuzz commands. \$\endgroup\$ Jun 3, 2017 at 2:43
  • 2
    \$\begingroup\$ +1 This is actually a really good idea for a code golf challenge! The small number of characters per line does seem impractical though 😅 I still love it though \$\endgroup\$ Jun 3, 2017 at 18:07

28 Answers 28

18
\$\begingroup\$

><>, 1 byte per line, 243 161 135 bytes

-26 bytes thanks to Jo King!

2D languages FTW! Although writing loops and branches using goto instructions instead of the 2D structure is not fun.

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

Try it online!, or watch it at the fish playground!

The fish swims downward along the code, using conditional gotos to skip things depending on what divides the accumulator.

I believe this meets the spec: whatever newlines are removed, the fish always hits the initial v (the only direction-changing instruction present), so the fish always swims downwards in the first column. Thus deleting a newline has the effect of simply removing the next character from the fish's path, and I don't think you can remove any of the characters without changing the output.

\$\endgroup\$
5
  • \$\begingroup\$ How many bytes is that? \$\endgroup\$
    – L3viathan
    Jun 4, 2017 at 9:13
  • 1
    \$\begingroup\$ @L3viathan, it's 243 bytes. (I'll edit that in.) \$\endgroup\$
    – Not a tree
    Jun 4, 2017 at 13:21
  • 1
    \$\begingroup\$ @L3viathan: I rearranged it a bit and now it's 161 bytes! \$\endgroup\$
    – Not a tree
    Jun 4, 2017 at 14:58
  • \$\begingroup\$ :( I don't think I can golf my answer down so much... \$\endgroup\$
    – L3viathan
    Jun 4, 2017 at 17:13
  • 1
    \$\begingroup\$ 135 bytes. and here's the horizontal version for reference \$\endgroup\$
    – Jo King
    Feb 20, 2018 at 9:14
18
\$\begingroup\$

Haskell, 3 bytes/line, 494 471 470 463 453 450 461 bytes

EDIT:

  • -26 bytes: Removed some redundant linebreaks and their associated comment markers, and changed -1+x into x-1.
  • +3 bytes: Oops, needed extra -- line after x-.
  • -1 byte: In f use c 47:[] instead of [c 47&0].
  • -7 bytes: Move newline handling to w.
  • -10 bytes: Inline a="Apple" and p="Pie" in # and use a dummy recursion for the 15 case.
  • -3 bytes: Inline w in f. Remove redundant -- between x and 15.
  • +11 bytes: Oops again! My string gap theory had a hole. Fixed by introducing % function. Finally made some automated testing to make sure there were no more surprises.

f takes an Int and returns 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}

Try it online!

Test source restrictions! (Line 70 is excluded from the testing because removing its newline causes an infinite loop without output.)

Version with the most important squeezing tricks removed:

{;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}

How it works

  • This code is written in the more rarely used indentation insensitive mode of Haskell, triggered e.g. by surrounding an entire program with {}. Since I'm actually defining a function rather than a whole program, I'm not quite sure how to count bytes; I've chosen to defensively count both the {}s and an extra ; declaration separator (the latter usually being a newline in normal Haskell mode.)
  • The main trick for making newlines "meaningful" is -- line comments, which make the next newline non-removable, and also a previous newline in the case when the previous line ends in an operator character (which is not itself part of a line comment).
  • The second trick is "string gaps", a sequence of whitespace between \ backslashes in string literals, indented for line continuations with possible indentation. A string gap with delimiters is removed from the parsed string.
    • If the newline of a string gap is removed, it becomes an added backslash in the string. For "Apple" and "Pie" this shows up directly in the output. For "8" and "9" a pattern match is used to give an error if the string has more than one character.
  • The third trick is the & and % operators, which allow forcing a line to end in an operator character for the first trick. We need this to end string literals, because \" is too wide to append --.
    • & is the general one, defined such that x&y=x.
    • % is defined such that [a]%y=a, allowing it to replace !!0 and simultaneously enforce that its string argument must have length 1.
  • The newline character poses a special problem, as \n seems impossible to fit in a string literal with only 3 bytes on the line.
    • Therefore, the more easily defined c x=["9"%0,"8"%0..]!!x is used to convert from an Int to a character, counting from the digit '9' downwards.
  • Because show is four characters, number output must be implemented by hand.
    • d is a list of the digit strings "1".."9".
    • n is an infinite list of number representations ["1","2","3",...] defined recursively using d.
  • # converts an Int x to its ApplePie form given an extra first argument that is the gcd of x with 15.
\$\endgroup\$
0
6
\$\begingroup\$

Haskell, 7 bytes/line, 339 bytes

The requirement for line breaks to be meaningful makes this a nontrivial challenge in Haskell. There are almost no ways to insert line breaks that cannot be removed, so everything has to be done with legitimately tiny statements.

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

Try it online!

\$\endgroup\$
6
\$\begingroup\$

Jelly, 3 2 bytes/line, 106 80 56 bytes

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

Rows and columns of the string literal get transposed, so removing newlines messes up their order.

The remaining lines are separate links/functions and contain function calls (¢), so they can only be concatenated if the function calls are eliminated as well.

Try it online!

\$\endgroup\$
6
\$\begingroup\$

TI-BASIC, 4 bytes per line

Since the goal is only to minimize the maximum line length, some of the lines are longer than they need to be, but the smallest I could make the longest line was 4 bytes. Therefore I felt it'd make the code easier to read if I merged the lines that could be combined without exceeding 4 bytes.

"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

Ungolfed

"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

About the Language and Limitations

TI-BASIC is a tokenized language, and, in this case, each of the tokens are 1 byte with the exception of the StrN variables, which are 2 bytes. Also, you can leave off closing parentheses most of the time. The remainder( function is 2 bytes, so using it would require at least 5 bytes (one for the function, two for the arguments, and one for the comma in remainder(I,3). Instead, I used the fPart( and not( functions to make it shorter, which are both 1 byte tokens. Also, you can see I used the built-in variable Ans quite a lot, since any expression that gets evaluated on a line by itself gets automatically stored to it. So, I can save a few bytes by splitting up the expressions and assignments.

Another strategy was to obviously minimize the string assignments. My method for doing so depended on the maximum line length in the rest of the code. Once I determined it to be 4 bytes, I was able to cram as much of each string on the same line as possible to minimize the amount of assignments I needed. I did this for the sake of readability.

The limiting factors in this code are the assignments to string variables and concatenation with string variables. The lines Ans→Str1 and Str1+Ans both are 4 bytes in total. I would have to find a way to eliminate string variables completely in order to further minimize the maximum line length in my code. Everything else can be shortened to a maximum of 3 bytes or less per line.

The problem there lies in assignments to numeric variables, such as 1→I. You can't golf that any further without somehow coming up with a solution without variables that doesn't exceed 2 bytes in line length. That happens to be impossible for this challenge.

Binary operators like + require the operator symbol and the left and right arguments. So without this, you would not be able to concatenate strings. Without string concatenation, there would be no way to display the strings required for this program to complete the challenge without exceeding 2 bytes in line length. Therefore the theoretical limit for this challenge in this language would be 3 bytes per line, which I was not able to attain.

\$\endgroup\$
6
  • \$\begingroup\$ But the longest line in the golfed version is 10 bytes If A and B \$\endgroup\$ Feb 14, 2018 at 21:04
  • \$\begingroup\$ @jmarkmurphy TI-BASIC is a tokenized language, and most tokens are represented by a single byte. I mentioned that in my description of the solution. You can read more about that on this wiki. \$\endgroup\$
    – kamoroso94
    Feb 14, 2018 at 21:07
  • \$\begingroup\$ But the premise was that editors should allow a minimum number of characters per line. I doubt that you are typing the tokens with an editor. And I don't think any of the other languages that are not purely interpreted are using a compiled object or tokenized byte count. \$\endgroup\$ Feb 14, 2018 at 21:11
  • \$\begingroup\$ @jmarkmurphy actually you do type the tokens in the editor. The Ans token is 1 byte, whereas the three consecutive characters Ans are 1, 2, and 2 bytes respectively for a total of 5. It's not an ASCII string, it's literally the token when you type it on the calculator. \$\endgroup\$
    – kamoroso94
    Feb 14, 2018 at 21:37
  • \$\begingroup\$ There's some consensus on this already on meta. \$\endgroup\$
    – kamoroso94
    Feb 14, 2018 at 21:45
6
\$\begingroup\$

Aceto, 1 byte per line, 230 bytes

Well, that wasn't fun to write. As a fungoid, Aceto's control structures heavily rely on its 2D nature, but we can work around that with lots, lots of conditional escapes (`). The only problem with those is that they affect the next command, regardless of its presence (all Aceto programs are squares, internally), which is why we need to align the program at some places by inserting empty lines at some points.

String literals can't really be used, but char literals can (in some places; again, we need to align them).

&
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
'

Called with 20, this prints:

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

All line breaks must be meaningful. Line breaks that can be removed and adjacent lines concatenated without an impact on the output, must be removed.

This is never the case here because it runs from the bottom to the top.

There's at least one place where we can save 2 bytes (by replacing the `X with a | or #), but I kept it as it is because of the runtime cost associated with running through a relatively big Hilbert curve.

I also ignored the implicit requirement for using \r or \r\n newlines because I think it's an unintentional mistake by the OP. If there's an edit or a comment reinforcing this requirement, I can change it without much trouble to use CR newlines instead.

The bytecount is based on Aceto's codegolfing encoding; Latin-7, in which £ is a single byte.

\$\endgroup\$
2
  • \$\begingroup\$ Re Assuming the three strings on the stack […] and This replacement is left as an exercise to the reader.: Please provide the full code required to solve the task at hand. As is, your solution is incomplete. It also lacks the byte count, which is the tie breaker for solutions with a score of 1. \$\endgroup\$
    – Dennis
    Jun 3, 2017 at 16:05
  • \$\begingroup\$ @Dennis I have now edited the answer to provide full working code. \$\endgroup\$
    – L3viathan
    Jun 3, 2017 at 17:15
6
\$\begingroup\$

C (gcc), 2 bytes per line, 374 368 320 310 262 bytes

I assume it can be golfed a bit more. Backslashes escaping newlines makes it sort of trivial.

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\
)\
)\
;\
}

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ @Ørjan Johansen Ah, quite right. \$\endgroup\$
    – gastropner
    Jun 22, 2018 at 18:00
  • \$\begingroup\$ You can remove a lot of the backslashes, reducing your tie-break score. Also, no need to separate two-byte tokens such as &&. \$\endgroup\$ Sep 10, 2018 at 8:48
5
\$\begingroup\$

Python 3, 4 bytes/line, 113 bytes

e=\
exec
def\
f(n\
):i\
=0;\
e('\
pri\
nt(\
i%3\
//2\
*"A\
ppl\
e"+\
i%5\
//4\
*"P\
ie"\
or-\
~i)\
;i+\
=1;\
'*n)

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ You know you don't need back slashes for newlines inside parens? \$\endgroup\$ Jun 2, 2017 at 22:48
  • \$\begingroup\$ oh, wait I didn't read the useful newlines rule \$\endgroup\$ Jun 2, 2017 at 22:49
  • \$\begingroup\$ @NickT: Addressed the rules change. \$\endgroup\$ Jun 2, 2017 at 23:03
5
\$\begingroup\$

PHP 7, 2 bytes per line

(#
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#
)#
)#
(#
)#
;#
\$\endgroup\$
4
  • \$\begingroup\$ How does that work with the dots? \$\endgroup\$
    – L3viathan
    Jun 4, 2017 at 13:23
  • \$\begingroup\$ @L3viathan Dots denote concatenation. They are used to build long strings from single characters. \$\endgroup\$
    – user63956
    Jun 4, 2017 at 14:34
  • \$\begingroup\$ I know that, but does PHP just make strings from unassigned variable names, or how does that work? I see no quote chars. \$\endgroup\$
    – L3viathan
    Jun 4, 2017 at 15:20
  • 2
    \$\begingroup\$ @L3viathan Those characters are constants. If a constant has not been defined, PHP uses its name as the value. \$\endgroup\$
    – user63956
    Jun 4, 2017 at 15:48
5
\$\begingroup\$

Perl 5, 2 bytes per line, 182 bytes

&
#
{'
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#
))

Try it online!

Perl's syntax is very forgiving, so a lot of gaps can be added to the code and comments added, which makes the core idea fairly straightforward. The main aim with this code is to build a string containing the code we want to run, and eval it. In Perl, it's possible to call a function using a string or variable with the &{...} notation, unfortunately however, eval isn't callable in this form, but evalbytes is, as long as you call it via the CORE:: namespace. Building that string was fairly straightforward and the program is passed directly to this call. The strings are built utilising the newlines as part of the XOR, to build these I used this script. To keep this valid, a few places have had to have comments placed, so that removing the newlines would result in non-functioning code.

The FizzBuzz routine was taken from primo's excellent answer.


Perl 5, 1 byte per line, 172 bytes

So, I (now) know this is invalid, because a bunch of the newlines can be removed, but since this was my original approach to the problem I'm adding it. It was fun see how far you can push Perl's syntax! I enjoyed this problem on its own merit, even though it's invalid.

&
{
(
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
)

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ Doesn't this break the "All line breaks must be meaningful" rule? \$\endgroup\$
    – 12Me21
    Feb 13, 2018 at 18:33
  • \$\begingroup\$ @12Me21 yeah, I've just been looking at that. So the first one breaks it if removed, but some of the others can indeed be removed, putting this as a length of 2. Damn, I spent ages getting an approach that worked with one char per line! \$\endgroup\$ Feb 13, 2018 at 18:37
  • \$\begingroup\$ @12Me21 I think I've got a solution that works for 2 now, I've added a golfed version of the 1 byte length since I spent the time to make it, damn rules! :) \$\endgroup\$ Feb 14, 2018 at 12:45
5
\$\begingroup\$

SmileBASIC, 9 7 bytes per line, 159 155 154 152 bytes

This was a really fun challenge. Unfortunately, the rule against unnecessary line breaks causes a few problems, (though luckily it doesn't affect the maximum line length here.) I had to add comments between lines like A%=I/3 and A=A%*3, since A%=I/3A=A%*3 is parsed correctly in SB. I was able to use a trick to leave out some comments, since replacing A with E makes that line invalid (It has something to do with numbers written using E notation, I think. 3E is considered an invalid number rather than a number and a variable name.)

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

The biggest limitation here is getting input. INPUT x is the simplest way allowed, the alternative being to define a function with an input value like DEF F x but that is still 7 characters. Making a conditional statement is also hard; I can't think of anything shorter than WHILE x.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ If A%=I/3A=A%*3 is syntactically valid but logically broken, you don't need the comment char. \$\endgroup\$
    – Nick T
    Feb 13, 2018 at 20:13
  • \$\begingroup\$ It's correctly parsed as A%=I/3 and A=A%*3, so the comment is required. \$\endgroup\$
    – 12Me21
    Feb 13, 2018 at 21:45
3
\$\begingroup\$

JavaScript (ES6), 3 bytes per line

Uses the global variable top to access the window object, from which we eval the following code:

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

You'll have to run it in the console as top is inaccessible from a sandboxed Stack Snippet.


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'\
`)
\$\endgroup\$
3
\$\begingroup\$

C#, 9 bytes per line, 248 242 230 bytes

Since C# doesn't care about linebreaks, it needs a oneline comment at the end of almost (thanks Ørjan Johansen) every line to comply with the rules. This program expects n as a command line argument. Here's with as many non-deletable newlines as possible:

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//
+//
@"
"//
)//
;//
}//
}//
}

But since the longest line is 9 bytes, other lines can get that long too, shaving off some bytes:

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+@"
");}}}
\$\endgroup\$
5
  • \$\begingroup\$ I have interpreted the concatenation as being "with no space between", so you don't need // between tokens that would fuse together, like static and void. \$\endgroup\$ Jun 4, 2017 at 1:17
  • \$\begingroup\$ @ØrjanJohansen Thanks! Saved 6 bytes \$\endgroup\$ Jun 4, 2017 at 15:47
  • \$\begingroup\$ I think maybe you can save more bytes by rearranging into var s="";if// (i%3==0// )s+=// "Apple"// ;if(i%5//. \$\endgroup\$ Jun 4, 2017 at 16:27
  • \$\begingroup\$ And there's a similar opportunity to move A from the first to the second line. \$\endgroup\$ Jun 4, 2017 at 16:38
  • \$\begingroup\$ And also saved 3 bytes by changing "\n" to @"", with the second quote on a new line, making that newline required too. \$\endgroup\$ Jun 4, 2017 at 18:04
2
\$\begingroup\$

Python 2, 5 bytes/line, 93 bytes

The max6 standard is already obsolete.

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

Try it online!

Python 2 and 3, 5 bytes/line, 100 bytes

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

Try it online!

\$\endgroup\$
2
\$\begingroup\$

JavaScript, max of 6 bytes/line, 528 bytes

Idea ripped from here.

Code ripped from here.

Thanks to Anders Kaseorg for g=eval, saving a byte per line.

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)

Unseperated:

n=prompt('');for(i=0;++i<=n;console.log(i%5?f||i:f+'Pie'))f=i%3?'':'Apple'
\$\endgroup\$
6
  • \$\begingroup\$ a=""+\n"f"+\n"o"+ ... and ending with eval(\na) is slightly shorter \$\endgroup\$
    – Value Ink
    Jun 2, 2017 at 21:35
  • \$\begingroup\$ The rules changed slightly (ApplePie, take an input), but your scheme should still be valid. \$\endgroup\$
    – Nick T
    Jun 2, 2017 at 22:04
  • \$\begingroup\$ The rule change invalidates @ValueInk’s suggestion, but you could still end with f=eval and f(a). \$\endgroup\$ Jun 2, 2017 at 22:07
  • \$\begingroup\$ @AndersKaseorg thank you :) didn't think of that \$\endgroup\$
    – Stephen
    Jun 3, 2017 at 3:27
  • 1
    \$\begingroup\$ You can save a byte by putting 2 characters in the string on the first line. \$\endgroup\$
    – 12Me21
    Feb 14, 2018 at 0:40
2
\$\begingroup\$

PHP, 4 Bytes/line

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

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ All line breaks must be meaningful. Line breaks that can be removed and adjacent lines concatenated without an impact on the output, must be removed. \$\endgroup\$ Jun 2, 2017 at 22:19
  • \$\begingroup\$ @JulianWolf I have change it \$\endgroup\$ Jun 2, 2017 at 22:36
2
\$\begingroup\$

APL (Dyalog), 5 bytes per line

∇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←''
M←3|⍵
M←0=M
O←M/A
M←5|⍵
M←0=M
M←M/P
O,←M
M←⍴O
M←0=M
M←M/⍵
O,←M
⎕←O⍝
}¨⍳⎕
∇

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Retina, 4 bytes/line

.+
$*      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.
$.&

Try it online!

\$\endgroup\$
2
\$\begingroup\$

R, 10 bytes per line, 800 bytes

The "meaningful linebreaks" rule made this challenging. Currently this just spells out fizzbuzz code into a string and then executes it.

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)

Try it online!

Here is the concatenated ApplePie code (adapted from MickyT's golf here).

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

And the ungolfed version of the parsing code:

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

Here I use toString to concatenate the list of symbols a into a single string. However, the default behavior is to separate each symbol with ,, so we call gsub to replace them with nulls. Then we pass it to parse and eval to do the dirty work.

It's possible that there's an approach that doesn't use this string parsing method and just straight up implements fizzbuzz, but it seems to me that using for or while or defining a function needs longer lines than the current approach.

\$\endgroup\$
2
\$\begingroup\$

Ruby, 10 5 bytes/line, 354 214 bytes

-140 bytes from the raw score from @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}"

How it works

Ruby will automatically concatenate sequences of string literals (except for single-character literals such as ?a) in the same statement. That means that x = "a" 'b' "c" %q{d} is equivalent to x = "abcd". We use this to split the FizzBuzz-like code into much smaller strings for calling eval with, since + will invalidate the program due to the removing-newlines rule, but the \ will cause syntax errors if the newlines are taken out!

\$\endgroup\$
6
  • \$\begingroup\$ I was just about to submit something similar \$\endgroup\$
    – anna328p
    Jun 2, 2017 at 21:41
  • \$\begingroup\$ The rules changed slightly ('ApplePie, take an input), but your scheme should still be valid. \$\endgroup\$
    – Nick T
    Jun 2, 2017 at 22:04
  • \$\begingroup\$ You can save a lot of bytes by adding two characters to the string on every line. \$\endgroup\$
    – Maya
    Feb 19, 2018 at 14:07
  • \$\begingroup\$ @NieDzejkob the primary scoring mechanism here is bytes per line, meaning that it's better to sacrifice total bytecount to reduce line length. \$\endgroup\$
    – Value Ink
    Feb 20, 2018 at 6:32
  • \$\begingroup\$ @NieDzejkob nvm I see what you mean now, it's since the initial eval line is longer than the rest, right? \$\endgroup\$
    – Value Ink
    Feb 20, 2018 at 7:02
1
\$\begingroup\$

Julia 0.6, 5 bytes per line, 168 bytes total

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)

Try it online!

The print brings this unavoidably (afaict) into the 5 bytes per line territory.

Ungolfed:

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

* is the string concatenation operator, so a*p*"\n" forms "ApplePie\n". |> is the function chaining (/piping) operator, so the chosen string gets sent as the argument to print. The sin is not used, it's just there because print needs to be in an array to have significant whitespace after it (using the # trick after it will bring the per line max byte count to 6).


If simply returning the output as an array is allowed, it can be done with 4 bytes max per line:

Julia 0.6, 4 bytes per line, 152 bytes total

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#
)

Try it online!

A function that takes n and returns an array containing the expected output. Max line length here is constrained by n-> - Julia needs that in a single line to parse it properly as the start of a lambda.

\$\endgroup\$
1
\$\begingroup\$

Pascal (FPC) -Sew, 6 bytes per line, 348 320 bytes

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.

Try it online!

Utilises FPC to get 6 bytes per line; without it, the result would be much worse. This is the smallest possible line width since after write must be either ; or ( (or unnecessary whitespace), so a special comment is inserted to avoid this. The features from FPC which influenced this answer are:

  1. // - starting one-line comments.
  2. Block comments in form {$<something>...} are compiler directives. If the directive does not exist, FPC will issue a warning (and on {$ ...} as well). In this program, { and $ are separated with a newline which will issue the warning when deleted.
  3. -Sew - Compiler also halts after warnings so that { and $ joined stop the compilation.
\$\endgroup\$
1
\$\begingroup\$

Japt, 3 bytes per line

Nearly managed to get it down to two bytes per line, but the return from map breaks if it's followed by a newline.
The FizzBuzz implementation itself is from the canonical FizzBuzz thread.


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

Try it online!

\$\endgroup\$
1
\$\begingroup\$

LOLCODE, 18 8 bytes per line, 303 bytes total

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

Try it online!

-10 bytes per line using the line-continuation character , thanks to Ørjan Johansen!

\$\endgroup\$
2
  • \$\begingroup\$ You can get that down to 8 with the … line continuation character. Try it online! \$\endgroup\$ Sep 10, 2018 at 18:32
  • \$\begingroup\$ I'm learning something new about these esolangs every day. Thanks, Oerjan! \$\endgroup\$ Sep 10, 2018 at 23:27
0
\$\begingroup\$

Python 2, 5 bytes/line

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\
)'

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ Careful! 'z\"' means the same thing as 'z\"', so the redundant newline rule means you’re not allowed to start a continuation line inside the string with ". \$\endgroup\$ Jun 2, 2017 at 23:00
  • \$\begingroup\$ @AndersKaseorg made it r'...' now \$\endgroup\$
    – Martmists
    Jun 3, 2017 at 10:21
  • \$\begingroup\$ This throws a SyntaxError. \$\endgroup\$ Jun 3, 2017 at 11:33
  • \$\begingroup\$ The TIO stops one number early. Also, the rules changed from using FizzBuzz to using ApplePie. \$\endgroup\$ Jun 4, 2017 at 1:47
0
\$\begingroup\$

Pip, 3 bytes per line, 72 bytes total

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

Try it online!

Pip is exceedingly flexible about whitespace, so the only strategy that seems feasible is to create a string, modify it in a way that requires the newlines not to be disturbed, and eval it.

We create a string where every other character is a newline, and take every other character of it using UW (unweave) and unary @ (get first element):

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

The result of @UW should be our ApplePie code, adapted from the FizzBuzz solution here. If any newlines in the string are deleted, this will not result in the full code, giving either a syntax error or incorrect output.

There are still two newlines outside the string. We made these mandatory by using the Y (yank) operator--which here acts as a no-op--together with the way Pip parses runs of uppercase letters:

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

So if these newlines are deleted, the program parses differently and doesn't do what it's supposed to.

\$\endgroup\$
0
\$\begingroup\$

Java 8, 7 bytes per line, 171 bytes

A void lambda taking an int. I suspect this obeys the requirement regarding newlines, but I can't prove it, and verifying it by brute force would take about a month on my computer. So it goes.

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");}

Try It Online

Pretty boring due to the line comments. The only interesting thing here is the use of a null System reference, which seems to be necessary in order to print to standard out in under 8 bytes per line. Note also that the print method call is the bottleneck.

Ungolfed with no comments:

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"
        );
}
\$\endgroup\$
0
\$\begingroup\$

JavaScript (ECMAScript6), 2 bytes per line

'\
'[
'\
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\
'\
`)
()


TLDR - Shorter explanation

I'm accessing the new Function(code) constructor to parse the string instead of eval(code). This constructor is available at every native function by doing anyFunction.constructor, like alert.constructor===Function. I'm using a function/method inside the String.prototype.big String.prototype.big.constructor.call(null, /*string*/) But accessing it directly from a string literal "".big and turned it to bracket notation. ""['big']['constructor']['call'](0, CODE) to be able to break it using the \.

Long explanation

The way we can make lines shorter is transforming code into a string and escaping the line ends, this will impose a limit of 2bytes per line.

So alert(1) becomes

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

But now your code is a string so we need to execute the string as code. I know at least 4 ways you can execute string as code:

  1. eval(code). Which takes at least 5 bytes to call eval(
  2. setTimeout(code, timeout). Runs function asyncronously, but optionally if you pass a string it will invoke eval internally.
  3. You can take advantage of the DOM and put your code inside a onclick="" attribute, but I could not manage to make the element creation part short.
  4. Invoking the Function constructor new Function() will parse your code into a anonymous function which you can call later (I used this).

All the native functions lives inside the window object and in javascript you can access object properties using the dot notation so eval() becomes window.eval(), or you can access properties using the bracket notation window['eval'](). You can take advantage of this to break the eval in multiple lines using the method described before. But you still have to type the window, one trick is that if you're not inside a frame, the top variable is also window, so window.eval becomes top.eval (3 bytes less).

w=top
w['eval']

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

So this will make the code minimum of 3 bytes. To make the code 2 bytes I used the new Function(/*string*/); constructor, but I had to be creative to access it without having to type it.

First, the Function constructor allows you to call it as a function omitting the new keyword, this reduce 4 bytes but it is also important for another reason. Calling the constructor as a function still returns a instance this allows us to turn new Function(code) to Function(code). Another importante thing is that the Function constructor have a call method that allows you to call any function but overriding the this reference, and the Function constructor itself being a function you can call a method on it self like Function.call(null, code).

All native functions are instances of the Function constructor, and all objects in javascript have a constructor property. So you can have access Function constructor on any native function like alert.constructor, and using the call method we can execute the constructor as a function. Now we have alert.constructor.call(null, code) returns a function.

combining the previous thechiniques we can turn it into alert['constructor']['call'](null, code)

Now we just need to find a short named function or method, so I choose the big() method inside the String constructor. So I can access it directly from a empty string "".big

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

Then I just broke every thing in 2 bytes

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Unfortunately, I think this is invalid since e.g. any line break between ' and ] can be removed and the program will still run successfully. \$\endgroup\$
    – darrylyeo
    Jun 5, 2017 at 1:44
  • \$\begingroup\$ I can't think of any way around this given a width of 2. But since we have nearly identical approaches, perhaps you can add an adapted version of your explanation to my answer, so not all is lost? \$\endgroup\$
    – darrylyeo
    Jun 5, 2017 at 1:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.