Pristine and Unique Code Bowling
Haskell, 39 45 50 52 60 bytes
main=do{(\ 陸 ⵙ商ߜ 新->pure fst)LT
EQ[]3
2$1}
Identifier main
has to have type IO a
for some type a. When the program is executed, the computation main
is performed, and its result is discarded. In this case its type is IO ((a,b)->a)
.
The result is an application of the function (λ a b c d e f → return fst)
,
a six-argument constant function returning the function fst (which gives the first element of a 2-tuple), injected into the IO monad. The six arguments are LT
(enum for less than), EQ
(enum for equality), empty list []
, 3
, 2
and 1
.
What would be spaces are replaced with unique characters that count as spaces: a tab, a non-breaking space, a formfeed, vertical tab, OGHAM SPACE MARK, regular space, newline and carriage return. If any of these are missing, there will be a mismatch in the number of arguments. The parameter names are chosen as three or four byte UTF-8 characters, 陸ⵙ商ߜ新
, carefully choosing characters that don't result in duplicate bytes.
Thanks to @BMO for his valuable contributions.
Hex dump:
00000000: 6d61 696e 3d64 6f7b 285c f0a4 b6b8 09ef main=do{(\......
00000010: a793 c2a0 e2b5 990c e595 860b df9c e19a ................
00000020: 80e6 96b0 2d3e 7075 7265 2066 7374 294c ....->pure fst)L
00000030: 540a 4551 5b5d 330d 3224 317d T.EQ[]3.2$1}
Try it online!
Jelly, 253 254 256 bytes
M“¢£¥¦©¬®µ½¿€ÆÇÐÑ×ØŒÞßæçðıȷñ÷øœþ !"#%&'()*+,-./0145689:;<=>?@ABCDEFGHIJKNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|~¶°¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ƁƇƑƓƘⱮƝƤƬƲȤɓƈɗƒɠɦƙɱɲƥʠɼʂƭʋȥẠḄḌẸḤỊḲḶṂṆỌṚṢṬỤṾẈỴẒȦḂĊḊĖḞĠḢİĿṀṄȮṖṘṠṪẆẊẎŻḅḍẹḥịḳḷṃṇọṛṣṭụṿẉỵẓȧḃċḋėḟġḣŀṁṅȯṗṙṡṫẇẋẏż”L»«’Ɗạ‘}237$¤¡
Try it online! or Verify it!
Turns out golfing languages can bowl...
- +1 byte by working in
‘
.Now only«»
are not used - +2 bytes with with
«»
. Now have the optimal score!
How?
The crucial feature of Jelly that makes this possible is that the opening and closing characters for string literals are not the same like in nearly all other languages.
The program structure is as follows:
M <239 character long string> L»«’Ɗạ‘}237$¤¡
M
finds the indices of its argument that point to maximal elements. All that matters is that with no argument to this program Jelly assigns 0
to the chain and Jelly errors when M
is applied to 0
.
To prevent M
from acting on 0
in the full program, we use the ¡
quick, which applies M
a number of times determined by the result of the link immediately preceding it. In this case that link is <239 character long string> L»«’Ɗạ‘}237$¤
.
L
takes the length of this string (239), and »«’Ɗ
decrements this to 238. The »«
part doesn't do anything but Ɗ
(last three links as a monad) makes it so that if they are deleted an error will occur. Then ạ
takes the absolute difference between the result of »«’Ɗ
and the monad ‘}237$
applied to the string. ‘
increments and is a monad, but the }
turns this into a dyad and applies it to it's right argument, 237
, yielding 238
. Thus ạ
yields 0
in the full program.
¤
links back to the string literal forming a nilad. The result of this is 0
, so M
is not applied at all, preventing any error.
Possible subprograms:
- If any part of the string is removed,
<string>..¤
will be nonzero andM
gets applied to0
, causing an error. - If any part of
L»«’Ɗạ‘}237$
is removed eitherM
will get applied to0
or there will be operations between the string and a number, resulting in aTypeError
. - If any of
¤¡
is removed,M
gets applied to0
. - If the string closing character
”
and both of’‘
get removed and“
doesn't, everything afterM
turns into a string soM
will act on0
.- If the string closing character
”
and’
get removed and“
doesn't, everything between”
and‘
turns into a list of integers.
- If the string closing character
- If
M
alone is removed there is a anEOFError
because¡
expects a link before the preceding nilad. - If
M“
and any number of characters after it is removed, there will be anEOFError
because the¤
looks for a nilad preceding it but doesn't find one.238
doesn't count because it is part of a monad.
This pretty much covers everything.
I previously hadn't used «»‘
because the latter two cannot be included in the string because they match the “
character to form things other than strings. «
can't be in a “”
string either but I don't know why.
Python 2, 20 21 33 39 45 50 bytes
Now very much a collaborative effort!
+2 thanks to Aidan F. Pierce (replace sorted({0})
with map(long,{0})
)
+8 thanks to dylnan (use of \
and newline to replace space; suggestions to move from 0
to a mathematical expression; replacing -1
with -True
; use of hexadecimal)
+11 thanks to Angs (4*23+~91
-> ~4836+9*1075/2
then later ~197836254+0xbCABdDF
-> ~875+0xDEAdFBCbc%1439/2*6
)
if\
map(long,{~875+0xDEAdFBCbc%1439/2*6})[-True]:q
Try it online! Or see the confirmation suite
0xDEAdFBCbc
is hexadecimal and evaluates to 59775106236
.
~
is bit-wise complement so ~875
evaluates to -876
.
%
is the modulo operator so 0xDEAdFBCbc%1439
evaluates to 293
.
/
is integer division so 0xDEAdFBCbc%1439/2
evaluates to 146
.
*
is multiplication so xDEAdFBCbc%1439/2*6
evaluates to 876
.
+
is addition so ~875+xDEAdFBCbc%1439/2*6
evaluates to 0
.
...no stripped version also evaluates to 0
.
{0}
is a set
containing a single element, 0
.
Calling sorted
with a set
as the argument yields a list, which may be indexed into with [...]
.
Without sorted
the code ({0})
would just yield the set
and this cannot be indexed into in the same fashion, if({0})[-True]:q
would raise a TypeError
.
Indexing in Python is 0-based and allows negative indexing from the back and True
is equivalent to 1
, hence sorted({0})[-True]
finds the element 0
, while sorted({0})[True]
will raise an IndexError
, as will sorted({})[-True]
and sorted({0})[]
is invalid syntax.
The 0
that is found is falsey so the body of the if
, q
, is never executed, however if it were it would raise a NameError
since q
has not been defined.
Since a non-empty list is truthy we cannot trim down to if[-1]:q
either.
See the confirmation suite to see: confirmation the bytes being unique; all the errors; and the success of the code itself.