| Bytes | Lang | Time | Link |
|---|---|---|---|
| nan | SAKO | 250317T194135Z | Acrimori |
| 064 | CASIO BASIC CASIO fx9750GIII | 250318T151519Z | madeforl |
| 054 | Janet | 250318T121248Z | xigoi |
| 081 | YASEPL | 240326T190225Z | madeforl |
| 058 | Swift | 240314T150324Z | macOSist |
| nan | 221007T154932Z | bigyihsu | |
| nan | Python | 210915T145634Z | Larry Ba |
| 027 | /// | 210515T230903Z | nph |
| 182 | CLCINTERCAL | 210916T084331Z | user1004 |
| 021 | APL Dyalog Extended | 200928T085417Z | rak1507 |
| 016 | Vyxal | 210915T015057Z | lyxal |
| 018 | ><> | 210915T033756Z | Bubbler |
| 028 | Julia 0.7 | 210505T102129Z | MarcMush |
| 029 | Vim | 210504T195104Z | DLosc |
| 047 | Scala | 201014T113929Z | Tomer Sh |
| 041 | R | 180421T181525Z | Giuseppe |
| 017 | Bash + Unix utilities | 170206T093349Z | Mitchell |
| 037 | Python 2 | 200502T162607Z | Surculos |
| 069 | Rust macros | 200502T160107Z | corvus_1 |
| 011 | GolfScript | 200109T100803Z | user8505 |
| 050 | Wren | 200109T085014Z | user8505 |
| 011 | Japt | 180517T024339Z | Bubbler |
| 042 | C gcc | 180421T160147Z | l4m2 |
| 018 | Vim + bc | 180114T191738Z | Endenite |
| 042 | Deorst | 180114T181121Z | caird co |
| 020 | Befunge98 PyFunge | 170907T024321Z | MercyBea |
| 042 | Cubically | 170907T034338Z | Kamil Dr |
| 035 | PHP 7.1 | 170206T091856Z | aross |
| 031 | sed | 170208T233931Z | Kevin |
| 048 | F# | 170212T225457Z | Lukas Bo |
| 042 | Python | 170206T092434Z | busukxua |
| 028 | PowerShell | 170212T194552Z | briantis |
| 109 | Java OpenJDK 8 | 170212T143625Z | DmitrySa |
| 063 | SmileBASIC | 170211T231100Z | 12Me21 |
| 7284 | Brainfuck | 170209T194904Z | Rupert T |
| 074 | JavaX | 170210T190940Z | Stefan R |
| 056 | C | 170210T213729Z | aka.nice |
| 053 | C | 170206T170132Z | Ahemone |
| 011 | Pyth | 170209T012551Z | insert_n |
| 115 | Brainfuck | 170209T010748Z | Ray |
| 042 | Haskell | 170207T175605Z | user3621 |
| 084 | C# | 170207T115843Z | adrianmp |
| 020 | Ruby | 170207T080007Z | G B |
| 013 | Pyth | 170208T022752Z | ericmark |
| nan | Ruby | 170206T101413Z | Value In |
| 081 | Java 7 | 170207T050636Z | Poke |
| 038 | Python | 170207T130305Z | Jonathan |
| 232 | Brainfuck way to many bytes | 170207T065703Z | CodyCode |
| 024 | Bean | 170207T055303Z | Patrick |
| 005 | Jelly | 170206T235859Z | Jonathan |
| 031 | RProgN | 170207T001739Z | ATaco |
| 077 | IBM/Lotus Notes Formula | 170206T145111Z | ElPedro |
| 013 | Retina | 170206T222057Z | Leo |
| 027 | Haskell | 170206T214848Z | xnor |
| 008 | Jelly | 170206T211354Z | user6213 |
| 065 | Haskell | 170206T123424Z | Laikoni |
| 011 | CJam | 170206T154745Z | Martin E |
| 024 | Befunge | 170206T150832Z | James Ho |
| 020 | Perl | 170206T143754Z | Dada |
| 029 | JavaScript ES6 | 170206T090711Z | Arnauld |
| 062 | Batch | 170206T135005Z | Neil |
| 039 | Haskell | 170206T130110Z | Zgarb |
| 014 | Retina | 170206T090311Z | Martin E |
| 023 | Perl 6 | 170206T100032Z | smls |
| 009 | Grime | 170206T095204Z | Zgarb |
| 017 | Mathematica | 170206T090808Z | Martin E |
| 009 | 05AB1E | 170206T094347Z | Adnan |
SAKO, 174 172 154 144 + 9 = 153 bytes
CALKOWITE:*W,I
BLOK(9):W
CZYTAJWIERSZ:W
I=-1
1)I=I+1
GDYW(I)=33:1,INACZEJ2
2)DRUKUJ(0):ABS((W(I)-48)*(1-0*ABS(W(I+1)-33))-MOD(I,2))
STOP1
KONIEC
Plus nine, because SAKO's native KW6 encoding doesn't support exclamation marks, so at least the compiler I usually use needs a -en ASCII flag.
String processing in SAKO is pretty long. Unfortunately we gotta lengthily declare those integers. Also, only strings of length 10 can be processed for shorter code.
My approach was rather simple. First, we count how many inversions there are and store it in I. Then we check if there is at least one factorial, if there is set Y to 0. Thanks to Y we can use exponentation to force any value to 1 (or leave unchanged if there aren't any factorials), and now just simple inversion using the remainder of I/2.
I declare Y as an integer because DRUKUJ(1,0):Y would take just as many bytes, and integer only code looks nicer. I shortened it by not declaring Y as an integer, instead assigning to and printing from W(0). Using I is also possible.
Shortened it even more by changing the loop logic and transforming an if to math (1-0*ABS(W(I+1)-33)). So now there isn't even Y.
CASIO BASIC (CASIO fx-9750GIII), 64 bytes
?→Str 1
StrSrc(Str 1,"0")+StrSrc(Str 1,"1")→N
Exp(StrMid(Str 1,N,1))
N<StrLen(Str 1)⟹1
(Ans+N-1) Rmdr 2
lols
Janet, 54 bytes
|(if(peg/match~{:main(+(*"0"-1)(*"!"(! :main)))}$)0 1)
Defines a PEG pattern that matches either a zero or an exclamation mark followed by anything that does not match the pattern.
YASEPL, 81 bytes
=1'=s®1=i`1!m¥i,1ſ""}7,exclamation,2!i+}2,s`2!1±m!3¥1,1®3}2,1,3!m$`3!3¥0,1®3+m%<
Swift, 58 bytes
let f={($0.last=="0" ?0:1)^($0+"").prefix{$0<"0"}.count%2}
Basically ended up being a port of @busukxuan's Python answer.
Lexurgy, 47 bytes
f:
{\0,\1} \!+=>\1
e:
\!\!=>*
g:
\! {\0,\1}=>* {\1,\0}
Explanation
# strip factorials
f:
{\0,\1} \!+=>\1
# !!X = X
e:
\!\!=>*
# apply !
g:
\! {\0,\1}=>* {\1,\0}
Python, 183 159 125 bytes
-34 bytes thanks to @wasif
Probably not going to beat anyone, but it was fun.
g=lambda x:x<2or x*f(~-x);from re import*;a,b,c=split("(\d+)",input())
exec("b=g(int(b));"*len(c)+"b=not b;"*len(a));print(b)
CLC-INTERCAL, 182 bytes.
The following source must be in Latin-1 or ISO-8859-1 encoding:
DO;1<-#1DO.9<-.9/;1SUB#1DOCOMEFROM:9DO.8<-"¥'.8¢:9'"~#1DOWRITEIN;1(1)DO:9<-.9~#16DO.7<-.9~#1DOWRITEIN;1DO.9<-"V'"'¥"'"&'"'¥"#1¢'.9~#4'"'~#1"¢.7'"~#1'¢.8"'~#1"¢#100'"~#5461DOREADOUT;1
Assumed I/O
- Uses standard input/output.
- Input: a line of the text. Does not matter trailing LF.
How to try it online
Try it online! Because of encoding issue, I recommend uploading and submitting the source rather than copying and pasting the code to the form. Also it may take very long time until the program ends.
How to test
Use the following shellscript:
#!/bin/sh
set -eu
cat<<'.' | awk 'BEGIN{ORS=""}$0=(NR>1?"":RS)$0' | iconv -f UTF-8 -t ISO-8859-1 >.i
DO;1<-#1
DO.9<-.9/;1SUB#1
DOCOMEFROM:9
DO.8<-"¥'.8¢:9'"~#1
DOWRITEIN;1
(1)DO:9<-.9~#16
DO.7<-.9~#1
DOWRITEIN;1
DONOTE remove the following long line to uncomment four sentences that begin with "DONOT.9<-" because it will result in timeout because of stupidly long expression.
DONOTE don't worry because they work equivalently.
DO.9<-"V'"'¥"'"&'"'¥"#1¢'.9~#4'"'~#1"¢.7'"~#1'¢.8"'~#1"¢#100'"~#5461
DONOT.9<-.9~#4
DONOT.9<-#1¢.9
DONOT.9<-.¥9~#1
DONOT.9<-"V'"'¥"'"&'".9"¢.7'"~#1'¢.8"'~#1"¢#100'"~#5461
DOREADOUT;1
.
wc -c .i >&2
sick .i
: >o
while read p _ q; do
o="$(
printf %s "$p" |
./.io |
tee -a o
printf X
)"
[ "X$o" = "X${q}X" ] &&
printf "%s: Passed\n" "$p" >&2 ||
printf "%s: Failed\n" "$p" >&2
done <<'.'
0 -> 0
1 -> 1
0! -> 1
1! -> 1
!0 -> 1
!1 -> 0
!0! -> 0
!1! -> 0
0!! -> 1
1!! -> 1
!!0 -> 0
!!1 -> 1
!0!! -> 0
!!!1 -> 0
!!!0!!!! -> 0
!!!1!!!! -> 0
.
cat o
How it works
DONOTE ;1SUB#1 shall be these:
'!' is #116
'0' is #101
'1' is #100
DONOTE actually first 16 bits are random bits
DONOTE that has at least a 1 bit
DONOTE when WRITEIN is done
DONOTE then second 16 bits are the values above
DONOTE EOF is really #0
DONOTE otherwise at least 2^16
DO;1<-#1 DONOTE for i/o
DO.9<-.9/;1SUB#1 DONOTE replaces every .9 with ;1SUB#1
DOCOMEFROM:9 DONOTE it is from label 1
DO.8<-"¥'.8¢:9'"~#1 DONOTE for fact
DOWRITEIN;1
(1)DO:9<-.9~#16 DONOTE '!' is #116 others are #101 or #100
DO.7<-.9~#1 DONOTE '0': 1, '1': 0
DOWRITEIN;1 DONOTE has trailing '!'?
DONOTE at this point .9 is '!': #116, EOF: #0, LF: #89
DONOTE explaining long expression
.9~#4 #1 if .9&0x04==0x04 else #0
'¥"#1¢'...'"'~#1 ^#1
"&'"..."¢.7'"~#1 &.7
'¥"'...'¢.8"'~#1 ^.8
"V'"..."¢#100'"~#5461 |#100
DO.9<-"V'"'¥"'"&'"'¥"#1¢'.9~#4'"'~#1"¢.7'"~#1'¢.8"'~#1"¢#100'"~#5461
DONOTE finally
DOREADOUT;1
```
APL (Dyalog Extended), 21 bytes
⍎⌽'!(\d.*)'⎕R'\1~'⍣≡⍞
Repeatedly shift any !s to the right with the fixpoint ⍣≡
!!!!0! -> !!!0!~ -> !!0!~~ -> !0!~~~ -> 0!~~~~
Then reverse with ⌽, and execute with ⍎
Vyxal, 16 bytes
`\d!+`1øṙ\!\¬VṘĖ
We do a little regex.
Explained
`\d!+`1øṙ\!\¬VṘĖ
`\d!+` # The string "\\d!+" ( a regex that matches the digit followed by !)
1øṙ # and replace it with "1" (because 0! = 1! = 1)
\!\¬V # replace any remaining "!" with "¬" (not)
ṘĖ # then reverse and evaluate
><>, 18 bytes
ib%:?\
+2%n;\i+3=l
Solved as part of LYAL CMC.
The basic idea is to process from left to right, doing the following:
- If the current char is
!(boolean negation), keep it on the stack so that stack height can be used for negation count. - If the current char is
0or1, take one more char and test if there's a factorial (modifying the number to 1 if there is). Apply negation, print as number, and halt.
Optimizations:
To get the final number, we can simply do
2%at the end, which means we can just add the stack height + 1 (because the final stack height would be one more than the number of negations).To discriminate between 48/49 and 33, we can do
b%(modulo 11, idea by Jo King).The (digit, factorial-or-EOF) combinations to handle are:
(48, 33) -> 1 (49, 33) -> 1 (48, -1) -> 0 (49, -1) -> 1We can use
48%11 = 4and49%11 = 5. Then a simple way to handle these combinations is to check if the sum of two numbers is 3 or not. We could use "is not 3" for the condition, but it turns out that we can negate it and remove the extra1+.
Julia 0.7, 28 bytes
~s=s[1]<'0'?!~s[2:end]:s>"0"
called with ~"!!0!", returns true or false
ungolfed:
function f(s)
if s[1] == '!'
return !f(s[2:end])
else
return s>"0"
end
end
s>"0" is false only for s=="0"
Vim, 29 bytes
:s/\d!!*\|1
A<C-r>=col('.')%2
<esc>d|
Explanation
If we normalize the number-and-factorial part, we can get the answer by counting the number of characters on the line mod 2.
:s/\d!!*\|1//<cr>
Substitute either 1) a digit followed by one or more !s or 2) a 1 digit with the empty string. (In the golfed version, the two final /s can be omitted.) This leaves a 0 if there was a lone 0 to begin with, and otherwise deletes the digit and everything after it.
A
Go to the end of the line and append something. The cursor is now positioned one column after the last character on the line.
<C-r>=col('.')%2<cr>
Calculate the column number mod 2 and insert that result (either 0 or 1).
<esc>d|
Leave insert mode; the cursor is now on the just-inserted character. Delete everything to the left of the cursor.
Scala, 65 63 47 bytes
s=>s.takeWhile(34>).length%2^(s.last-48).abs%14
Many thanks to user for -16 chars!!!
R, 41 bytes
+eval(parse(t=gsub("\\d!+",1,scan(,""))))
Two and a half years later, finally fixed the bug pointed out by JayCe, by switching * in the regex to a +...
The + is just to coerce the logical to numeric.
Bash + Unix utilities, 21 17 bytes
sed s/.!!*$/1/|bc
Added a TIO link to the test suite.
This must be saved in a file and run as a program. If you try to enter the command directly from the command line, it won't work because !! is expanded due to history substitution being enabled in bash's interactive mode. (Alternatively, you can turn history substitution off with set +H.)
Python 2, 37 bytes
f=lambda s:s<"0"and 1-f(s[1:])or"0"<s
Sometimes returns True/False instead of 0/1, which is allowed I think.
How
- The factorial part can be evaluated simply as
"0"<s. This is 0 only whensis 0, and 1 ifsis anything else (e.g1or0!!). - The negation part is evaluated using recursion. If
sstarts with!(s<"0"), recurs as1-f(s[1:]).
Rust macros, 69 bytes
macro_rules!f{(!$($x:tt)*)=>{1-f!($($x)*)};(0)=>{0};($($x:tt)*)=>{1}}
Defined a macro f that takes a sequence of tokens (including !, 0 and 1) as input and produces a token sequence that evaluates to the expected result. Port of a Haskell answer.
Explanation
macro_rules! f {
(! $($x:tt)*) => { // match an exclamation mark followed by any number of token trees
1 - f!($($x)*) // expand to 1- and call the macro recursively
};
(0) => { // match a 0 that's not followed by anything
0 // replace with a 0
};
($($x:tt)*) => { // match any number of token trees
1 // replace with 1
}
}
GolfScript, 11 bytes
Blatant port (not copying the whole algorithm) of Martin Ender's CJam answer. At least I got the same length.
.)\;48=!\~;
Explanation
. # Add a fresh copy of the input
) # Generate the input without the last item
# and the last item of the input
\ # Swap so that the first output of ) is on top
; # Remove so that there is only the last item
48= # Is the item equal to 48 (ASCII '0') ?
! # If not (0), there are !'s before either 0 or 1
# and the result is obviously 1 (0 negated)
# If yes (1), the last item is going to be 0,
# and the result is 0 (1 negated).
\ # Take the fresh unused copy of the input to the top
~ # Apply the input to the top
; # (Due to postfix evaluation the trailing
# !'s are applied to the number.)
# Discard the applied number, which is garbage
# Implicitly output the result
```
Japt, 11 bytes
+OxUe/\d!/1
How it works
+OxUe/\d!/1
Ue Apply recursive replace to input string...
/\d!/1 which replaces digit+! to 1
Ox Eval the result as vanilla JS
+ Cast the result (String or Boolean) to Number
The idea is similar to Arnauld's JS answer though I came up with it independently.
Vim + bc, 18 bytes
:s/\d!\+/1␊V!bc␊
␊ is a literal newline
Explanation
:s/\d!\+/1␊ Replace any digit followed by factorials with 1 ("0!!!" -> "1"; "1!!" -> "1")
V!bc␊ Evaluate the not-operators using the `bc` command, similarly to this answer
Vim, 36 bytes
:s/\d!\+/1␊:s/!!//g␊:s/!1/0␊:s/!0/1␊
␊ is a literal newline
Explanation
:s/\d!\+/1␊ Replace any digit followed by factorials with 1 ("0!!!" -> "1"; "1!!" -> "1")
:s/!!//g␊ Remove all double nots ("!!!!!" -> "!"; "!!!!!!" -> "")
:s/!1/0␊ Replace !1 with 0
:s/!0/1␊ Replace !0 with 1
Deorst, 42 bytes
o1:ER'[01]!+'gs''p@
'(!!)+'gst!0gso0@t!1gs
Regex based solution. Input must be quoted ('0')
How it works
Example input: '!!!0!!!!'
o1 - Push '1'; STACK = ['!!!0!!!!', '1']
: - Duplicate; STACK = ['!!!0!!!!', '1', '1']
ER - Reverse; STACK = ['1', '1', '!!!0!!!!']
'[01]!+' - Push '[01]!+'; STACK = ['1', '1', '!!!0!!!!', '[01]!+']
gs - Regez replace; STACK = ['1', '!!!1']
''p - Push ''; STACK = ['1', '!!!1', '']
@ - Swap; STACK = ['1', '', '!!!1']
'(!!)+' - Push '(!!)+'; STACK = ['1', '', '!!!1', '(!!)+']
gs - Regex replace; STACK = ['1', '!1']
t!0 - Push '!0'; STACK = ['1', '!1', '!0']
gs - Regex replace; STACK = ['!1']
o0 - Push '0'; STACK = ['!1', '0']
@ - Swap; STACK = ['0', '!1']
t!1 - Push '!1'; STACK = ['0', '!1', '!1']
gs - Regex replace; STACK = ['0']
Alternative, 27 bytes
t!1@t0$gs''p@
t!!gs'^\d'gcB
Requires input to be quoted ('0'). Based on Leo's Retina answer
How it works
t!1 - Push '!1'; STACK = ['!!!0!!!!', '!1']
@ - Swap; STACK = ['!1', '!!!0!!!!']
t0$ - Push '0$'; STACK = ['!1', '!!!0!!!!', '0$']
gs - Regex replace; STACK = ['!!!0!!!!']
''p - Push empty string; STACK = ['!!!0!!!!', '']
@ - Swap; STACK = ['', '!!!0!!!!']
t!! - Push '!!'; STACK = ['', '!!!0!!!!', '!!']
gs - Regex replace; STACK = ['!0']
'^\d' - Push '^\d'; STACK = ['!0', '^\d']
gcB - Count occurrences; STACK = [0]
Befunge-98 (PyFunge), 22 20 bytes
Golfed off 2 bytes because I realized that if I used k instead of j to do the logical notting to account for a 0 without a factorial, I didn't have to mod the ASCII value of 0 or 1 by 2. I did have to move the code because removing the 2% left a hole between the $~ and #< previously.
-kv$!~:'!
#<k!.@.$$~
Explanation
The first line:
-kv$ Does nothing because the top of the stack is 0
! Nots the top, so we start with a value of 1
~ Gets a character from input
- :'! Pushes (that character - the value of '!')
kv If that value is not 0 (the character was not '!'), go to the next line
$! If it is, Throw away the extra '!' and not the number below it (originally 1)
Repeat from the ~
Now that we're on the second line, we have notted 1 for each ! before the number. If there is a ! after the number, we can just print this value, but if there isn't we need to adjust for whether or not the number is 0.
The second line:
< Directs the IP left.
# Doesn't skip anything because it's at the beginning of a line
~ If we reached EOF (no factorials), the ~ will reverse the IP's direction
$$ No EOF: Drop the '!' we just read along with the number
@. Print (1 notted the appropriate amount of times) and end
#< EOF: Wrap around and skip the arrow
k! Not the top n + 1 times, where n is the ASCII value of 0 or 1 (48 or 49)
If the number is 1, it will be notted 50 times (even),
yielding no change.
If the number is 0, we not it 49 times (odd), which makes up for
starting with a 1 at the beginning.
.@ Print this value and exit
Cubically, 42 bytes
UD3(L2~:7=3)6+13=7!6{<0%6&}~:7=3?6L2-6=0%6
For some unknown reason it exits with an error when the digit is 1, but it outputs the correct result regardless. The following is my basic algorithm:
- Start with 0
- Invert for each
! - If digit is
1invert again and output (any number of trailing!are irrelevant), ending the program - If there is a
!after the digit, invert - Output (any further
!are irrelevant)
And a more thorough explanation:
UD3 Sets RIGHT to 33 and LEFT to 15
(L2~:7=3)6 Flips TOP between 0 and 15 each time the input is ASCII 33 '!'
+13=7!6 If the next character is NOT ASCII 15+33 '0':
{<0%6&} output 1 if TOP is 15, 0 otherwise, then exit
~:7=3?6 If the next character is ASCII 33 '!':
L2 flip TOP
-6=0%6 Output 1 if TOP is 0, 0 otherwise
PHP 7.1, 58 55 54 37 35 bytes
Note: uses IBM-850 encoding
echo!!$argn[-1]^strspn($argn,~Ì)%2;
Run like this:
echo '!!!0!!!!' | php -nR 'echo!!$argn[-1]^strspn($argn,~Ì)%2;';echo
> 0
Explanation
echo
strspn($a=$argv[1],~Ì) # Count the number of leading exclamation marks.
% 2 # Make 0 (even) or 1 (odd).
^ !!$a[-1]; # Negate with factorial part (truthy value of the
# last char):
# - "0" is considered falsy.
# - "1" or "!" is considered truthy.
Tweaks
- Saved 3 bytes by using IBM-850 encoding
- Saved a byte by changing the regex slightly
- Saved 17 bytes, new version without long function names and return
- Saved 2 bytes by using
-R(which makes$argnavailable)
sed, 36 33 31 bytes
Pure sed, no bc / shell utils. Works on GNU sed < 4.3; 33 bytes on BSD and GNU 4.3+.
s/.!!*$/1/
:
s/!0/1/
s/!1/0/
t
Straightforward enough if you're familiar with sed; commented for those who aren't:
# Since 0! == 1! == 1 and factorial has precedence, just collapse any trailing "!"
s/.!!*$/1/
# Define an anonymous label
:
# Invert 0 if needed
s/!0/1/
# Invert 1 if needed
s/!1/0/
# If a change was made, go back to the anonymous label.
t
Test:
% cat 109248.sed
s/.!!*$/1/
:l
s/!0/1/
s/!1/0/
tl
% wc -c 109248.sed
33 109248.sed
% cat cases
0
1
0!
1!
!0
!1
!0!
!1!
0!!
1!!
!!0
!!1
!0!!
!!!1
!!!0!!!!
!!!1!!!!
% sed -f 109248.sed cases
0
1
1
1
1
0
0
0
1
1
0
1
0
0
0
0
% gsed -f 109248.sed cases
0
1
1
1
1
0
0
0
1
1
0
1
0
0
0
0
%
F#, 69 48 Bytes
let rec f=function|'!'::t->1-f t|'0'::[]->0|_->1
Tests
let test (input,expected) =
let result = input |> Seq.toList |> f
if result = expected then
printfn "%s = %d" input result
else
printfn "Error at %s" input
[
("0", 0)
("1", 1)
("0!", 1)
("1!", 1)
("!0", 1)
("!1", 0)
("!0!", 0)
("!1!", 0)
("0!!", 1)
("1!!", 1)
("!!0", 0)
("!!1", 1)
("!0!!", 0)
("!!!1", 0)
("!!!0!!!!", 0)
("!!!1!!!!", 0)
] |> Seq.iter test
Python, -44- 42 bytes
Saved 2 bytes thanks to Zgarb!
lambda x:(x[-1]=='0')^len(x.rstrip('!'))%2
Step by step:
x[-1]!='0'
ifxends with1or!⇔xdoesn't end with0, the factorial portion must have value1, else0^len(x.rstrip('!'))%2
exploit xor's property as a "conditional not". The condition in this case is if the length of initial!s is odd. However,.rstripdoesn't remove the number from the string so the length calculated is offset by 1, therefore the condition is inverted- The offset by 1 in step 2 is corrected by changing
!=to==in step 1. Zgarb suggested using a difference comparison operator rather than applying another inversion, saving 2 bytes.
PowerShell, 28 bytes
+($args-replace'\d!+',1|iex)
Explanation
Replace any digit followed by 1 or more ! with 1 (to solve the factorials), then just execute the remaining string which is valid code. The result will be boolean so I use unary + to convert it to a number.
Java (OpenJDK 8), 109 bytes
s->{int l=s.length(),n=(l>1?s.split("[01]")[0]:s).length();return l<2?s:(l-n<2&&s.charAt(n)<'1')==n%2>0?1:0;}
SmileBASIC, 63 bytes
INPUT S$WHILE"#">S$[0]N=!N
S$[0]="
WEND?(VAL(S$)||LEN(S$)>1)!=N
I don't think this is the best way...
Brainfuck, 85 72 (84) bytes
,[>-[-----<->]<++[>++++[-<++++>]+<[[+],[[-]>-<]]]>[<<+[-->]>[<],>-]<]<+.
to return numerically, or
,[>-[-----<->]<++[>++++[-<++++>]+<[[+],[[-]>-<]]]>[<<+[-->]>[<],>-]<]-[-----<+>]<--.
for ASCII text. > may also be prefixed to avoid memory wrapping.
Loops over the input.
On 1, ends.
On "!", toggles bool a stored as 0 or 255.
On "0", toggles if there is no trailing bit, then ends.
Memory labels | BOOL | INPUT | FLAG |
, first input
[ # loop on INPUT
>-[-----<->]<++ subtract 49 == "1"
[ # case not "1"
>++++[-<++++>] add 16 since 49 take 16 == "!"
+ set FLAG
< move to INPUT
[ # case "0"
[+], clear and new INPUT
[ # case "0!"
[-]>-< clear INPUT and FLAG
]
]
]
> move to FLAG
[ # case "!" or "0" without tail
<<+[-->]>[<] not the BOOL
, take new input
>- clear FLAG
]
< move to INPUT
]
+. return 0 or 1
Or for text response, replace the last line with
-[-----<+>]<--. add 49 for "0" or "1" conversion and return
JavaX, 77 74 bytes
!7p{print(repeatMultiReplace3(args[0],splitAtSpace("0! 1 1! 1 !0 1 !1 0";}
C, 56 bytes
c=1;f(char*a){c=-c;*a&16?c+=1-*a-1[a],c&=2,c/=2:f(a+1);}
Hint: only the last two bits count.
The basic idea was to use least significant bit for storing result of factorial, and next bit for storing the negation, then xoring the two.
c=0;
for(;*a<34;a++)c^=2; // invert the 2nd bit at each negation
while(*a)c|=*a++; // '0' ends with bits 00, '1' and '!' ends with bits 01, so this OR will let the first bit to resut of factorial (LSB) and leave the 2nd bit unchanged
c=((c>>1)^c)&1; // apply the negation (2nd bit) on the factorial (1st bit)
But it makes our intentions too clear. First, we don't need a loop for the factorial, and we can allways take 2 char, the 2nd being eventually a NULL terminator will have neutral 00 end bits. This is much like the answer Mathematics is fact. Programming is not from Ahemone, but longer and less elegant so far.
c=0;
while(*a++<34)c^=2; // invert the 2nd bit at each negation
c|=*a,c|=*--a; // '0' and NULL ends with bits 00, '1' and '!' ends with bits 01, so this OR will let the first bit to resut of factorial (LSB) and leave the 2nd bit unchanged
c=((c>>1)^c)&1; // apply the negation (2nd bit) on the factorial (1st bit)
C isn't going to win anyway, so let's trade some golf for some obfuscation: replace the last expression with something else, assuming 2-complement: -x == (~x+1) and observe how the last two bits evolve
- ...00 -> ...11+1 -> ...00
- ...01 -> ...10+1 -> ...11
- ...10 -> ...01+1 -> ...10
- ...11 -> ...00+1 -> ...01
We see that the LSB is unchanged via c=-c, and the 2nd bit becomes the xor of last two bits. So we can just pick this second bit with c>>=1,c&=1 or c&=2,c/=2;
Of course, the bit inversion ~x is useless, just adding+1 has the same effect.
But there is a reason behind it:
what if we would replace the XOR flip/flop with negated op?
at each neg -...01 becomes ...11 et vice et versa
If we then subtract 1, we have either ...00 or ...10 at the end of the loop.
We are back to our original solution.
c=1;
while(*a++<34)c=-c;
c-=1;
c|=*a,c|=*--a;
c=-c;
c&=2,c/=2;
And let's see what happens if we add the factorial bit instead of ORing:
...00 becomes 00 or 01 or 10 in case of '0' , '0!'||'1' , '1!'.
...10 becomes 10 or 11 or 00.
So using + gives the same parity than | on last two bits, even if we accidentally add a bit twice du to '1!' case.
Now we just have to roll the final c-=c inside the loop, and replace the + by - for getting our obfuscated solution.
Ah and also use recursion to take a functional style disguise, but of course with non reentrant, ugly static variable assignment side effect, else there would be no "advantage" to code in C ;)
C, 68 62 61 53 bytes
c;e(char*a){for(c=1;*a<34;a++)c^=1;c=a[1]?c:*a&1^!c;}
Squeezed out a few more bytes with some abuse
Pyth, 11 bytes
s.v:z"0!"\1
Explanation
s.v:z"0!"\1
: Replace...
z in the input...
"0!" the string "0!"...
\1 with the string "1".
.v Evaluate the result. Since only the first expression is evaluated,
anything after the number will be ignored.
s Convert the result to an integer and implicitly print it.
This is necessary because ! returns True/False, not 0/1.
Brainfuck, 115 bytes
>,[->++++[<-------->-]<[--------------->,[<[-]+>-]<<[->-[>+<+]>[-<+>]<<]>>++++++[-<++++++++>]<.>>+<]>-[<<+>,>[-]]<]
Ungolfed:
% 0: inverter count
% 1: result
% 2: if/else flag; tmpspace in inner loop 0
>1,[
->2++++[<-------->-]<1 subtract 33 (!)
[
% we've reached the number
---------------
% now it's either 0 or 1
% check next char; If it's not 0 then it's '!'
% 0! = 1! = 1!...! so we only need to determine if at least one ! exists
>2,
[<[-]+>-]<1
% apply inversions
<0
[->1
% invert cell 1 once each iteration
% cell 1 is 0 or 1
- % cell 1 is 255 or 1
[>+<+] % cell 1 is 0; cell 2 is 1 iff cell 1 should be 1
>2[-<+>]<1 % cell 1 is 1 or 0
<0]
% print result
>1>++++++[-<++++++++>]<1.
>>2+< % tape={0 r 0 1}
]
>2-[ % we haven't seen the number yet
<<0+>1,>2 % add to inverter count
[-]
]<1
]
Haskell, 42
There must be a better way to do this...
f(h:t)|h=='!'=1-f t|h=='1'=1|t==[]=0|1<2=1
C#, 88 84 bytes
Saved 4 bytes thanks to TheLethalCoder.
s=>{var c=s.Replace("!","")[0];int b=s.IndexOf(c);return(s.Length>++b?b:b+c-49)%2;};
Previous version:
s=>{var c=s.Replace("!","")[0];int b=s.IndexOf(c),n=s.Length-b>1?1:c-48;return(n+b)%2;};
Full program with commented method and test cases:
using System;
class MathIsFactProgrammingIsNot
{
static void Main()
{
Func<string, int> f =
s=>
{
// removes all the exclamation marks and extracts the 0 or 1 digit
var c = s.Replace("!","")[0];
// number of exclamation marks before the digit
int b = s.IndexOf(c),
// the number of exclamation marks after the digit increased by 1 (because of the digit)
n = s.Length - b > 1 ? 1 : c-48;
// if no exclamation marks are present, converts the digit from the string to an integer
return (n + b) % 2; // applies binary negation
};
// test cases:
Console.WriteLine(f("0")); // 0
Console.WriteLine(f("1")); // 1
Console.WriteLine(f("0!")); // 1
Console.WriteLine(f("1!")); // 1
Console.WriteLine(f("!0")); // 1
Console.WriteLine(f("!1")); // 0
Console.WriteLine(f("!0!")); // 0
Console.WriteLine(f("!1!")); // 0
Console.WriteLine(f("0!!")); // 1
Console.WriteLine(f("1!!")); // 1
Console.WriteLine(f("!!0")); // 0
Console.WriteLine(f("!!1")); // 1
Console.WriteLine(f("!0!!")); // 0
Console.WriteLine(f("!!!1")); // 0
Console.WriteLine(f("!!!0!!!!")); // 0
Console.WriteLine(f("!!!1!!!!")); // 0
}
}
Ruby, 22 21 20 bytes
->s{(s=~/!*$|0$/)%2}
Explanation:
- First case, I got some '!' at the end, remove them, get length modulo 2.
- Second case, no '!', if last character is zero then remove it, get length modulo 2
- If the last character is 1, back to the first case
(-1 byte stealing @Value Ink's idea)
Pyth, 13 bytes
Code
s.v:z"\d!+""1
There may be a way to shave off a couple of bytes, but alas.
Explanation
s # Cast to an integer (Python's int()).
.v # Evaluate (Python's eval()). This handles the negations.
: # Regex substitution. The following three expressions are its arguments.
z # Argument 1: what to replace in. This is equal to the (unevaluated) input string.
"\d!+" # Argument 2: what to replace. This is a regex that matches a number followed by one or more !'s.
"1 # Argument 3: what to replace to. The string "1" (ending quote not needed in Pyth).
You can check it out here or run the test suite here. I have no earthly idea how to (or if one actually can) use the test suite feature to run tests as opposed to just evaluating a bunch of inputs at once, but if someone else knows, I'm all ears.
Java 7, 105 82 81 bytes
int a(char[]a){int b=0,c=0;for(;a[b++]<34;c^=1);return(b<a.length?1:a[b-1]&1)^c;}
Old regex-ish solution
int a(String a){a=a.replace("0!","1").replaceAll("1.*","1");int b=a.length()-1;return b%2^a.charAt(b)&1;}
Python, 38 bytes
lambda s:(s[1::2]>s[::2])^ord(s[-1])%2
An unnamed function taking an input string s and returning an integer 0 or 1.
s[1::2] is a slice of the input string that starts at index 1 and has a step size of two:
'Like this' -> 'ieti'
s[::2] is similar but starts at the default index of 0:
'Like this' -> 'Lk hs'
The test (s[1::2]>s[::2]) checks if the 0-based index of the '0' or '1' is odd, i.e. if we need to complement.
This works because the ordering of strings is checked lexicographically with any non-empty string greater than the empty string, and with ASCII ordering, so '1'>'0'>'!'. This is a byte shorter than the simpler s.index(max(s))%2.
The ord(s[-1])%2 checks to see if the last character is not a '0' (for valid input), and results in an integer (whereas the same length (s[-1]!='0') would return a boolean).
This works because the last character of the input, s[-1], will be a '0', '1', or '!' which have ASCII code points 48, 49, and 33 respectively, which are 0, 1, and 1 modulo 2.
The ^ then performs a bitwise exclusive or operation on the two above values, returning an integer since one input, the right one, is an integer. If the left is True the complement of the right is returned, if the left is False the right is returned, as required.
Brainfuck - way to many bytes (232 bytes)
Clearly the wrong language for winning in code golf. Mainly I noticed a lack of anyone using this esolang. There is a good online interpreter bf interpeter or you can actually watch what the program does using this bf visualizer.
>>>>>,[>+++[<---------------->-]<<<<<<[-]+>[-]>>>>[-[<<[>+<<<<->>>[<<+>>-] ]<<[>>+<<-]<[>>+<<[-]]>>>>>[-]]<<<<<[>>>++<<<-]>+>>>>[-]]<<<<-[>>+<<[-]]>>>>,]<<->[<[-]+>[-]]<<[<[-]>>[<<+>>[-]]+<<[->>-<<]>-]>>[-]+++[<++++++++++++++++>-]<.
Bean, 24 bytes
Hexdump:
00000000 26 4a c1 53 a0 17 53 d0 80 a0 5d 20 80 0a a1 80 &JÁS .SÐ. ] ..¡.
00000010 81 00 25 3a ae a1 ab 24 ..%:®¡«$
00000018
Equivalent JavaScript:
+eval(a.replace(/.!+$/,1))
Sorry for stepping on your toes, Arnauld.
Explanation:
Takes first line of input as unformatted string in a, and replaces any digit followed by one or more ! with 1, so that the rest can be eval'd by JavaScript.
Try the demo, or the test suite
Jelly, 5 bytes
VeMḂ$
Monadic function expecting a string. Inputs with leading !s cause a 1 to be printed to STDOUT along the way, so the TIO link I give is a test harness that prints the input-output pairs beneath the first line of output.
How?
VeMḂ$ - Monadic link: string
V - eval the string
- the implicit input of 0 causes !...! to evaluate to 1 (which gets printed),
- the result is the evaluation of the rest: "0"=0; "0!"=1; "1"=1; "1!"=1; ...
e - exists in?
$ - last two links as a monad:
M - Maximal indexes - the "0" and "1" characters are greater than "!",
- so this results in a list of one item [i] where
- i is the 1-based index of the 0 or 1 character.
Ḃ - %2 (vectorises) - [i%2], so a 0 if we need to logically negate and a 1 if not
- hence we check equality with e rather than inequality.
RProgN, 31 bytes
~'(!*1?)0?(!*)'{L`x=L2%x+0>1*}R
Explained
~'(!*1?)0?(!*)'{L`x=L2%x+0>1*}R
~ # Zero Space Segment
'(!*1?)0?(!*)' # A pattern string, matching any number of !'s with optionally a 1, optionally an uncaptured 0, and any number of !'s
{ } # An anonymous function, which takes two arguments. The last !'s and the optional 1 with the first 1's.
L # Get the length of the last !'s
`x= # Set 'x' to equal it.
L2% # Get the length of the first !'s with the optional 1, mod 2, giving us the boolean portion.
x+ # Add x
0>1* # If the total is larger than 0, converted to a number. If there are any leading !'s, this will always be 1, otherwise, it will be the boolean of the left handside.
R # Replace the input string via the function matching the first pattern.
IBM/Lotus Notes Formula - 77 bytes
@Eval(@Left(a;@If(@Like(a;"%1%");"1";"0"))+@If(@Ends(a;"!");"1";@Right(a;1)))
There is no TIO for Notes Formula so a screenshot of all test cases is shown below:
How it works
@Eval() evaluates a string as an expression
First we check if the input string in field (input) a contains 1 or 0 and take all characters to the left of whichever it is which will be a string of ! characters. We don't care how many. @Eval() will take care of that.
Next we look to see if there is a ! at the end of the string. If there is we append 1 to the ! string (0! and 1! are both 1 - it doesn't matter how many ! characters there are at the end) otherwise we append the last character unchanged because it is not a ! and could be either a 1 or a 0.
We now have a string containing the leading inversions plus a number defined by whether there are any factorial characters so we can feed this to @Eval() and get the results above.
Retina, 13 bytes
A somewhat weird approach, but it's short and it works.
0$
!1
!!
^\d
With the first two lines we replace an ending 0 with !1: with this replacement we now know that the part of our string from the digit onwards is equal to 1.
Next two lines, remove pairs of !: double negation erases itself, and we already accounted for factorial with the previous step.
Last line, match a digit at the start of the string and return the number of matches: if the negations have all been eliminated we'll find a match (and as we said before we know this is equal to 1), if there's still a negation this won't match.
Haskell, 27 bytes
f('!':b)=1-f b
f"0"=0
f _=1
Each leading ! complements the output for the rest of the expression, done as 1-. We keep flipping until we hit a digit. If the remaining is just "0", the result is 0. Otherwise, it's a 1 or is followed by one or more !, so the result is 1.
Jelly, 8 bytes
œr”!LḂ=V
This is a function (monadic link) that takes one argument and returns via its return value. (It also often writes junk to standard output as a side effect, but we don't care about that.)
Explanation
œr”!LḂ=V
œr”! Take {the input}, with all trailing ! deleted
L Take the length of this
Ḃ Take the parity of that length
= Return 0 if unequal, 1 if equal to:
V the value of {the input} when eval'ed as a niladic Jelly program
First, note that as the input always consists of some number of !, followed by a digit, followed by more !, that if we delete the trailing ! and take the length, we'll end up with one plus the number of leading ! in the program. Taking the parity of this will return 0 if there were an odd number of !, or 1 if there were an even number of !. Comparing to 0 is a "not" function, whereas comparing to 1 is the identity function; thus œr”!LḂ= effectively implements the "treat leading ! as NOT operators" part of the question.
As for the second half, handling factorials, ! is a factorial operation in Jelly, so if the program has no leading !, we can solve the problem directly with a simple eval (V). If the program does have leading !, those will be interpreted as taking the factorial of 0 (possibly multiple times), producing a return value of 1, which will be printed to standard output and discarded once a digit is seen; thus, they have no impact on the return value of the function that's my submission to the question.
Haskell, 67 65 bytes
f s|foldr(\_->not)(last s`elem`"1!")$fst.span(<'0')$s="1"|1<3="0"
Try it online! Usage: f "!!!0!!!!"
Saved two bytes thanks to @nimi.
CJam, 12 11 bytes
r_W='0=!\~;
Try it online! Test suite (prints a 1 for each correct test case).
r e# Read input.
_W='0= e# Duplicate and check whether the string ends in '0'. This is the
e# only case in which the factorial part results in 0.
! e# Negate this to get the actual result of the factorial part.
\ e# Swap with the input.
~ e# Evalute the input as CJam code. The leading `!` will apply the logical
e# negations to the factorial result. The 0 or 1 will then push a junk value
e# which is potentially negated a few times as well, by the factorials.
; e# Discard the junk value.
Befunge, 24 bytes
~"!"-:#v_$1+
*+2%!.@>0~`
This starts by counting the number of ! characters read from stdin. The first character that isn't a ! will either be a 0 or 1, but in the process of testing for ! we will have subtracted 33, making it either 15 or 16. We then read one more character, that will either be an ! or EOF, and compare if that is less than 0 (i.e. EOF).
Taking those three data points - the exclamation count (c), the digit value, (d), and the end-of-file condition (e) - we can calculate the result as follows:
!((c + d*e) % 2)
Multiplying the digit value by the end-of-file condition means it will be converted to zero if the digit was followed by a !, thus giving it the same modulo 2 value as a 1 (which remember has been converted to 16). But before applying the modulo 2, we add the initial exclamation count, which effectively toggles the modulo 2 result as many times as their were ! prefixes. And finally we not the result since our baseline values for 0 and 1 are the opposite of what we need.
Looking at the code in more detail:
~ Read a character from stdin.
"!"- Subtract 33 (ASCII for '!').
: _ Make a duplicate and check if zero (i.e. is it a '!').
$1+ If so, drop the duplicate, increment a counter, and repeat.
v Otherwise move to the second line, leaving the digit value on the stack.
>0~` Read one more character and check if less than 0 (i.e. EOF).
* Multiple by the digit value, making it zero if not followed by EOF.
+ Add to the exclamation count.
2% Modulo 2 the result.
! Then not that value.
.@ And finally write to stdout and exit.
Perl, 20 bytes
19 bytes of code + -p flag.
s/\d!+/1/;$_=0+eval
Perl's negation returns undef or 1, so I use 0+ to numerify the result 0+undef returns 0. Besides that, not much to say about the code.
JavaScript (ES6), 43 41 29 bytes
s=>+eval(s.replace(/.!+$/,1))
Non-regex method (41 31 bytes)
Below is my initial approach. It's slightly more interesting, but significantly longer still a bit longer even after a significant optimization by Neil (10 bytes saved).
f=([c,...s])=>1/c?c|s>'':1-f(s)
Test cases
let f =
s=>+eval(s.replace(/.!+$/,1))
;[
"0", "1", "0!", "1!", "!0", "!1", "!0!", "!1!", "0!!",
"1!!", "!!0", "!!1", "!0!!", "!!!1", "!!!0!!!!", "!!!1!!!!"
].map(
s => console.log(s, '=>', f(s))
)
Batch, 62 bytes
@set/ps=
@set s=%s:0!=1%
@set s=%s:!!=%
@cmd/cset/a%s:1!=1%
Takes input on STDIN. Batch actually understands leading !s correctly for this challenge, but the trailing !s need to be dealt with, which takes three steps:
- Change
0!to1 - Delete pairs of
!!(this is safe for the!!s before the digit too) - Delete any remaining trailing
!(which by now can only be after a1)
Haskell, 39 bytes
f('!':b)="10"!!read[f b]
f[a]=a
f _='1'
Defines a function f, which takes a string and returns a character.
Try it online!
Explanation
There are three cases: input begins with !, input has length 1, and everything else.
f('!':b)= -- If input has head '!' and tail b,
"10"!! -- we index into the string "10"
read[f b] -- using f b converted to int. This essentially inverts f b.
f[a]= -- If input has only one character, we know it's a digit,
a -- so we can just return it.
f _= -- In all other cases, we know the input is a digit followed by !s,
'1' -- so we can return '1'.
Retina, 20 15 14 bytes
Thanks to Leo for saving 1 byte.
0!
1
!!
^1|!0
Explanation
0!
1
Turn 0! into 1. We don't care about any other trailing !s, the resulting number is the same as if we had applied all factorials.
!!
Cancel pairs of negations. This may also cancel some factorials, but that's irrelevant.
^1|!0
Count the number of matches of this regex, which is either 1 or 0 and gives the desired result.
Perl 6, 32 28 23 bytes
{m/(\!)*(1|0.)*/.sum%2}
How it works
{ } # A lambda.
{m/ / } # Match the lambda argument against the regex:
(\!)* # Zero or more `!`.
# (First capture will be an array with one element per negation).
(1|0.)* # A `1`, or a `0` and another character, zero or more times.
# (Second capture will be a one-element array if the factorial
# part evaluates to 1, and an empty array otherwise.)
.sum # Add the lengths of the two captures,
%2 # and return that sum modulo 2.
Grime, 14 12 9 bytes
e`\0!~\!_
Explanation
This matches the input against a pattern, printing 1 for match and 0 for no match.
e`\0!~\!_
e` Match entire input against this pattern:
! not
\0 a sole 0
~ xor
\! exclamation mark
_ followed by this pattern matched recursively.
The idea is this.
If the input begins with a digit, then the recursive part \!_ always fails, and \0! succeeds unless we have a single 0.
Their xor succeeds unless the input is a single 0.
If the input begins with a !, then \0! always succeeds, and \!_ succeeds if the recursive match succeeds.
Their xor succeeds exactly when the recursive match fails, thus negating it.
Mathematica, 25 17 bytes
Input[]/.!x_:>1-x
Takes input from a user prompt. Assumes Mathematica's notebook environment for implicit printing. To make it a command-line script, wrap it in Print[...] or to make it an argumentless function (which then takes input from the prompt), append &.
Mathematica has both of the required operators (with the required precedence), so we can just "eval" the input (which is done automatically by Input[]), but the logical negation operator doesn't work on integers (so it will remain unevaluated). If there's a !x left in the result, we replace it with 1-x.
A couple of fun facts about the evaluation:
- Mathematica actually also has the double factorial operator
!!, which computesn*(n-2)*(n-4)*..., but applied to0or1it still gives1, so it doesn't matter that0!!!!!will actually be parsed as((0!!)!!)!. - Even though Mathematica leaves
!0and!1unevaluated, it does know that!is self-inverse, so it will automatically cancel all pairs of leading!. After theToExpressionwe're always left with one of0,1,!0,!1.
05AB1E, 9 bytes
Code:
.V¹'!ÜgG_
Uses the CP-1252 encoding. Try it online! or Verify all test cases!
Explanation:
.V # Evaluate the input as 05AB1E code. This computes the factorial part.
'!Ü # Remove trailing exclamation marks..
¹ # ..from the first input
g # Get the length of the resulting string
G # Do the following length - 1 times:
_ # Negate the number
