Add preview of 1984-2019
The 2020 winners are hinted it, but the source code is not there,
nor are the hints. Someone could look into the HTML and
see what was commented out, but that is not a problem because
WHO won is known and the name of their AWARD is known already.
Moreover a number of the winners have talked about what their
entirs do, so the commented out spoiler text is not a bit problem.
One will find HTML commented out with:
<!-- XXX remove when 2020 is ready
2020 links here
XXX remove when 2020 is ready -->
The "XXX remove when 2020 is ready" string is found at the
start and end comment blocks. Again, soneone could read
what was commented out, but that is OK since most of that
information is known or can be known. The following files
have such HTML comment blocks in them.
./winners.html
./years-spoiler.html
./years.html
In addition, ./all/summary.txt was modified to not
include the 2020 entries for the momemt.
The 2020 winner code AND write-ups are NOT part of this set.
p.s. The all/all.tar.bz2 does not contain the 2020 source code (yet?).
This commit is contained in:
1 parent
28efc67f5d
commit
c0663537cb
1683 files changed
+220064
No files matched your search
Binary file not shown.
+158
@@ -0,0 +1,158 @@
|
||||
2018/MANIFEST
|
||||
2018/Makefile
|
||||
2018/algmyr/Makefile
|
||||
2018/algmyr/hint.html
|
||||
2018/algmyr/hint.text
|
||||
2018/algmyr/prog.c
|
||||
2018/algmyr/prog.orig.c
|
||||
2018/algmyr/spoiler.png
|
||||
2018/anderson/Makefile
|
||||
2018/anderson/hint.html
|
||||
2018/anderson/hint.text
|
||||
2018/anderson/prog.c
|
||||
2018/anderson/prog.orig.c
|
||||
2018/bellard/Makefile
|
||||
2018/bellard/fruits.bin
|
||||
2018/bellard/hint.html
|
||||
2018/bellard/hint.text
|
||||
2018/bellard/lena512.bin
|
||||
2018/bellard/prog.c
|
||||
2018/bellard/prog.orig.c
|
||||
2018/bellard/vintage_cars.bin
|
||||
2018/burton1/Makefile
|
||||
2018/burton1/hint.html
|
||||
2018/burton1/hint.text
|
||||
2018/burton1/prog.c
|
||||
2018/burton1/prog.nowarn.c
|
||||
2018/burton1/scripthd
|
||||
2018/burton2/Makefile
|
||||
2018/burton2/README
|
||||
2018/burton2/ansi
|
||||
2018/burton2/c++11
|
||||
2018/burton2/c++14
|
||||
2018/burton2/c++98
|
||||
2018/burton2/c11
|
||||
2018/burton2/c99
|
||||
2018/burton2/discrepancies
|
||||
2018/burton2/fixed_iocccsize.c
|
||||
2018/burton2/freqcount
|
||||
2018/burton2/hint.html
|
||||
2018/burton2/hint.text
|
||||
2018/burton2/ioc_without_quote
|
||||
2018/burton2/ioccc.kw.freq
|
||||
2018/burton2/iocccbug01.c
|
||||
2018/burton2/iocccbug02.c
|
||||
2018/burton2/iocccbug03.c
|
||||
2018/burton2/iocccbug04.c
|
||||
2018/burton2/iocccbug05.c
|
||||
2018/burton2/iocccbug06.c
|
||||
2018/burton2/java8
|
||||
2018/burton2/kandr
|
||||
2018/burton2/kandr2
|
||||
2018/burton2/manpage
|
||||
2018/burton2/mkkeywords
|
||||
2018/burton2/patch
|
||||
2018/burton2/prog.c
|
||||
2018/burton2/results
|
||||
2018/burton2/results.k
|
||||
2018/burton2/runtest
|
||||
2018/burton2/spotcheck
|
||||
2018/burton2/spotdiff
|
||||
2018/burton2/src.doc.rot13
|
||||
2018/burton2/tac.c
|
||||
2018/burton2/tac.man
|
||||
2018/burton2/test01.c
|
||||
2018/burton2/test02.c
|
||||
2018/burton2/test03.c
|
||||
2018/burton2/test04.c
|
||||
2018/burton2/test05.c
|
||||
2018/burton2/test06.c
|
||||
2018/burton2/test07.c
|
||||
2018/burton2/test08.c
|
||||
2018/burton2/test09.c
|
||||
2018/burton2/test10.c
|
||||
2018/burton2/test11.c
|
||||
2018/burton2/test12.c
|
||||
2018/burton2/test13.c
|
||||
2018/burton2/test14.c
|
||||
2018/burton2/tokenfix
|
||||
2018/burton2/unob.sh
|
||||
2018/burton2/v7unix
|
||||
2018/ciura/Makefile
|
||||
2018/ciura/hint.html
|
||||
2018/ciura/hint.text
|
||||
2018/ciura/prog.c
|
||||
2018/ciura/prog.orig.c
|
||||
2018/endoh1/Makefile
|
||||
2018/endoh1/golem.txt
|
||||
2018/endoh1/hint.html
|
||||
2018/endoh1/hint.text
|
||||
2018/endoh1/invisible.txt
|
||||
2018/endoh1/prog.c
|
||||
2018/endoh1/prog.orig.c
|
||||
2018/endoh1/smily.txt
|
||||
2018/endoh2/Makefile
|
||||
2018/endoh2/hint.html
|
||||
2018/endoh2/hint.text
|
||||
2018/endoh2/prog.c
|
||||
2018/endoh2/run.sh
|
||||
2018/ferguson/FILES
|
||||
2018/ferguson/Makefile
|
||||
2018/ferguson/hint.css
|
||||
2018/ferguson/hint.html
|
||||
2018/ferguson/hint.text
|
||||
2018/ferguson/prog-simple.c
|
||||
2018/ferguson/prog.c
|
||||
2018/ferguson/prog.orig.c
|
||||
2018/ferguson/test-strings.txt
|
||||
2018/ferguson/test.sh
|
||||
2018/ferguson/weasel.1
|
||||
2018/ferguson/weasel.man
|
||||
2018/ferguson/weasel.spec
|
||||
2018/giles/Makefile
|
||||
2018/giles/hint.html
|
||||
2018/giles/hint.text
|
||||
2018/giles/ioccc.txt
|
||||
2018/giles/prog.c
|
||||
2018/giles/sand.txt
|
||||
2018/giles/sand.txt.orig
|
||||
2018/guidelines.txt
|
||||
2018/hint.css
|
||||
2018/hou/Makefile
|
||||
2018/hou/hint.html
|
||||
2018/hou/hint.text
|
||||
2018/hou/input.json
|
||||
2018/hou/prog.c
|
||||
2018/hou/prog.orig.c
|
||||
2018/iocccsize.c
|
||||
2018/iocccsize.mk
|
||||
2018/mills/Makefile
|
||||
2018/mills/boot.dat
|
||||
2018/mills/bsd.img.bz2
|
||||
2018/mills/hint.html
|
||||
2018/mills/hint.text
|
||||
2018/mills/prog.c
|
||||
2018/mills/v0.image.fs
|
||||
2018/mills/v6.tape.gz
|
||||
2018/poikola/Makefile
|
||||
2018/poikola/hint.html
|
||||
2018/poikola/hint.text
|
||||
2018/poikola/poikola.tex
|
||||
2018/poikola/prog-doc.c
|
||||
2018/poikola/prog.c
|
||||
2018/poikola/prog.orig.c
|
||||
2018/rules.txt
|
||||
2018/vokes/Makefile
|
||||
2018/vokes/example-1.txt
|
||||
2018/vokes/example-2.txt
|
||||
2018/vokes/example-tab.txt
|
||||
2018/vokes/hint.html
|
||||
2018/vokes/hint.text
|
||||
2018/vokes/ioccc.txt
|
||||
2018/vokes/prog.c
|
||||
2018/whowon.html
|
||||
2018/yang/Makefile
|
||||
2018/yang/hint.html
|
||||
2018/yang/hint.text
|
||||
2018/yang/prog.c
|
||||
2018/yang/spoiler.html
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
#!/usr/bin/env make
|
||||
#
|
||||
# 2018 makefile
|
||||
#
|
||||
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
|
||||
# is licensed under:
|
||||
#
|
||||
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
|
||||
#
|
||||
# See: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
|
||||
################
|
||||
# tool locations
|
||||
################
|
||||
#
|
||||
SHELL= /bin/bash
|
||||
CP= cp
|
||||
CPP= cpp
|
||||
GUNZIP= gunzip
|
||||
BUNZIP2= bunzip2
|
||||
GZIP_PROG= gzip
|
||||
BZIP2= bzip2
|
||||
CURL= curl
|
||||
DD= dd
|
||||
LD= ld
|
||||
MAKE= make
|
||||
RM= rm
|
||||
SED= sed
|
||||
TAR= tar
|
||||
TRUE= true
|
||||
MKDIR= mkdir
|
||||
MV= mv
|
||||
TR= tr
|
||||
GREP= grep
|
||||
SORT= sort
|
||||
UNIQ= uniq
|
||||
STRIP= strip
|
||||
|
||||
# Set X11_LIBDIR to the directory where the X11 library resides
|
||||
#
|
||||
#X11_LIBDIR= /usr/X11R6/lib
|
||||
#X11_LIBDIR= /usr/X11/lib
|
||||
X11_LIBDIR= /opt/X11/lib
|
||||
|
||||
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
|
||||
#
|
||||
#X11_INCDIR= /usr/X11R6/include
|
||||
#X11_INCDIR= /usr/X11/include
|
||||
X11_INCDIR= /opt/X11/include
|
||||
|
||||
# ANSI compiler
|
||||
#
|
||||
# Set CC to the name of your ANSI compiler.
|
||||
#
|
||||
CC= cc
|
||||
|
||||
|
||||
###############
|
||||
# IOCCC winners
|
||||
###############
|
||||
#
|
||||
WINNERS= anderson algmyr bellard burton1 burton2 ciura endoh1 endoh2 ferguson \
|
||||
giles hou mills poikola vokes yang
|
||||
|
||||
|
||||
###################
|
||||
# build all entries
|
||||
###################
|
||||
#
|
||||
all:
|
||||
@for i in ${WINNERS} ; do \
|
||||
echo "(cd $$i && $(MAKE) X11_LIBDIR=${X11_LIBDIR} X11_INCDIR=${X11_INCDIR} $@)"; \
|
||||
(cd $$i && $(MAKE) "X11_LIBDIR=${X11_LIBDIR}" "X11_INCDIR=${X11_INCDIR}" $@); \
|
||||
done
|
||||
|
||||
# alternative executable
|
||||
#
|
||||
alt:
|
||||
@for i in ${WINNERS} ; do \
|
||||
echo "(cd $$i && $(MAKE) X11_LIBDIR=${X11_LIBDIR} X11_INCDIR=${X11_INCDIR} $@)"; \
|
||||
(cd $$i && $(MAKE) "X11_LIBDIR=${X11_LIBDIR}" "X11_INCDIR=${X11_INCDIR}" $@); \
|
||||
done
|
||||
|
||||
|
||||
###############
|
||||
# utility rules
|
||||
###############
|
||||
#
|
||||
everything: all alt
|
||||
|
||||
clean:
|
||||
@for i in ${WINNERS} ; do \
|
||||
echo "(cd $$i && $(MAKE) $@)"; \
|
||||
(cd $$i && $(MAKE) $@); \
|
||||
done
|
||||
|
||||
clobber:
|
||||
@for i in ${WINNERS} ; do \
|
||||
echo "(cd $$i && $(MAKE) $@)"; \
|
||||
(cd $$i && $(MAKE) $@); \
|
||||
done
|
||||
${RM} -f iocccsize
|
||||
${RM} -rf iocccsize.dSYM
|
||||
|
||||
nuke: clobber
|
||||
@for i in ${WINNERS} ; do \
|
||||
echo "(cd $$i && $(MAKE) $@)"; \
|
||||
(cd $$i && $(MAKE) $@); \
|
||||
done
|
||||
|
||||
install:
|
||||
@for i in ${WINNERS} ; do \
|
||||
echo "(cd $$i && $(MAKE) $@)"; \
|
||||
(cd $$i && $(MAKE) $@); \
|
||||
done
|
||||
|
||||
|
||||
##################
|
||||
# 133t hacker rulz
|
||||
##################
|
||||
#
|
||||
love:
|
||||
@for i in ${WINNERS} ; do \
|
||||
echo "(cd $$i && $(MAKE) $@)"; \
|
||||
(cd $$i && $(MAKE) $@); \
|
||||
done
|
||||
|
||||
haste:
|
||||
@for i in ${WINNERS} ; do \
|
||||
echo "(cd $$i && $(MAKE) $@)"; \
|
||||
(cd $$i && $(MAKE) $@); \
|
||||
done
|
||||
|
||||
waste:
|
||||
@for i in ${WINNERS} ; do \
|
||||
echo "(cd $$i && $(MAKE) $@)"; \
|
||||
(cd $$i && $(MAKE) $@); \
|
||||
done
|
||||
|
||||
make:
|
||||
@for i in ${WINNERS} ; do \
|
||||
echo "(cd $$i && $(MAKE) $@)"; \
|
||||
(cd $$i && $(MAKE) $@); \
|
||||
done
|
||||
|
||||
easter_egg:
|
||||
@for i in ${WINNERS} ; do \
|
||||
echo "(cd $$i && $(MAKE) $@)"; \
|
||||
(cd $$i && $(MAKE) $@); \
|
||||
done
|
||||
|
||||
fabricate fashion form frame manufacture produce:
|
||||
@for i in ${WINNERS} ; do \
|
||||
echo "(cd $$i && $(MAKE) $@)"; \
|
||||
(cd $$i && $(MAKE) $@); \
|
||||
done
|
||||
|
||||
sandwich:
|
||||
@for i in ${WINNERS} ; do \
|
||||
echo "(cd $$i && $(MAKE) $@)"; \
|
||||
(cd $$i && $(MAKE) $@); \
|
||||
done
|
||||
|
||||
deep_magic:
|
||||
@for i in ${WINNERS} ; do \
|
||||
echo "(cd $$i && $(MAKE) $@)"; \
|
||||
(cd $$i && $(MAKE) $@); \
|
||||
done
|
||||
|
||||
magic:
|
||||
@for i in ${WINNERS} ; do \
|
||||
echo "(cd $$i && $(MAKE) $@)"; \
|
||||
(cd $$i && $(MAKE) $@); \
|
||||
done
|
||||
|
||||
# The IOCCC resident astronomer states
|
||||
#
|
||||
supernova:
|
||||
@for i in ${WINNERS} ; do \
|
||||
echo "(cd $$i && $(MAKE) $@)"; \
|
||||
(cd $$i && $(MAKE) $@); \
|
||||
done
|
||||
|
||||
charon: supernova
|
||||
@for i in ${WINNERS} ; do \
|
||||
echo "(cd $$i && $(MAKE) $@)"; \
|
||||
(cd $$i && $(MAKE) $@); \
|
||||
done
|
||||
|
||||
pluto: supernova
|
||||
@for i in ${WINNERS} ; do \
|
||||
echo "(cd $$i && $(MAKE) $@)"; \
|
||||
(cd $$i && $(MAKE) $@); \
|
||||
done
|
||||
@@ -0,0 +1,286 @@
|
||||
#!/usr/bin/env make
|
||||
#
|
||||
# 2018 makefile
|
||||
#
|
||||
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
|
||||
# is licensed under:
|
||||
#
|
||||
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
|
||||
#
|
||||
# See: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
|
||||
################
|
||||
# tool locations
|
||||
################
|
||||
#
|
||||
SHELL= /bin/bash
|
||||
CP= cp
|
||||
CPP= cpp
|
||||
GUNZIP= gunzip
|
||||
BUNZIP2= bunzip2
|
||||
GZIP_PROG= gzip
|
||||
BZIP2= bzip2
|
||||
CURL= curl
|
||||
DD= dd
|
||||
LD= ld
|
||||
MAKE= make
|
||||
RM= rm
|
||||
SED= sed
|
||||
TAR= tar
|
||||
TRUE= true
|
||||
MKDIR= mkdir
|
||||
MV= mv
|
||||
TR= tr
|
||||
GREP= grep
|
||||
SORT= sort
|
||||
UNIQ= uniq
|
||||
|
||||
# Set X11_LIBDIR to the directory where the X11 library resides
|
||||
#
|
||||
#X11_LIBDIR= /usr/X11R6/lib
|
||||
#X11_LIBDIR= /usr/X11/lib
|
||||
X11_LIBDIR= /opt/X11/lib
|
||||
|
||||
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
|
||||
#
|
||||
#X11_INCDIR= /usr/X11R6/include
|
||||
#X11_INCDIR= /usr/X11/include
|
||||
X11_INCDIR= /opt/X11/include
|
||||
|
||||
# Compiler warnings
|
||||
#
|
||||
#CWARN=
|
||||
#CWARN= -Wall
|
||||
#CWARN= -Wall -Wextra
|
||||
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
|
||||
#CWARN= -Wall -Wextra -Weverything
|
||||
#CWARN= -Wall -Wextra -Weverything -pedantic
|
||||
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
|
||||
|
||||
# Silence warnings that ${CWARN} would normally complain about
|
||||
#
|
||||
CSILENCE= -Wno-string-plus-int -Wno-empty-body -Wno-unused-result
|
||||
#CSILENCE= -Wno-implicit-int
|
||||
|
||||
# compiler standard
|
||||
#
|
||||
#CSTD=
|
||||
#CSTD= -ansi
|
||||
CSTD= -std=c11
|
||||
|
||||
# compiler bit architecture
|
||||
#
|
||||
# Some entries require 32-bitness:
|
||||
# ARCH= -m32
|
||||
#
|
||||
# Some entries require 64-bitness:
|
||||
# ARCH= -m64
|
||||
#
|
||||
# By default we assume nothing:
|
||||
#
|
||||
ARCH=
|
||||
|
||||
# defines that are needed to compile
|
||||
#
|
||||
CDEFINE=
|
||||
#CDEFINE= -DIOCCC=25
|
||||
|
||||
# include files that are needed to compile
|
||||
#
|
||||
CINCLUDE=
|
||||
#CINCLUDE= -include stdlib.h
|
||||
#CINCLUDE= -include stdio.h
|
||||
#CINCLUDE= -include stdlib.h -include stdio.h
|
||||
#CINCLUDE= -I ${X11_INCDIR}
|
||||
|
||||
# optimization
|
||||
#
|
||||
# Most compiles will safely use -O2. Some can use only -O1 or -O.
|
||||
# A few compilers have broken optimizers or this entry make break
|
||||
# under those buggy optimizers and thus you may not want anything.
|
||||
# Reasonable compilers will allow for -O3.
|
||||
#
|
||||
#OPT=
|
||||
#OPT= -O
|
||||
#OPT= -O1
|
||||
#OPT= -O2
|
||||
OPT= -O3
|
||||
|
||||
# default flags for ANSI C compilation
|
||||
#
|
||||
CFLAGS= ${CSTD} ${CWARN} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
|
||||
|
||||
# Libraries needed to build
|
||||
#
|
||||
LIBS=
|
||||
#LIBS= -L ${X11_LIBDIR}
|
||||
|
||||
# ANSI compiler
|
||||
#
|
||||
# Set CC to the name of your ANSI compiler.
|
||||
#
|
||||
# Some entries seem to need gcc. If you have gcc, set
|
||||
# both CC and MAY_NEED_GCC to gcc.
|
||||
#
|
||||
# If you do not have gcc, set CC to the name of your ANSI compiler, and
|
||||
# set MAY_NEED_GCC to either ${CC} (and hope for the best) or to just :
|
||||
# to disable such programs.
|
||||
#
|
||||
CC= cc
|
||||
#CC=clang
|
||||
MAY_NEED_GCC= gcc
|
||||
|
||||
|
||||
##############################
|
||||
# Special flags for this entry
|
||||
##############################
|
||||
#
|
||||
OBJ= prog.o
|
||||
DATA=
|
||||
TARGET= prog
|
||||
#
|
||||
ALT_OBJ= prog.orig.o
|
||||
ALT_TARGET= prog.orig
|
||||
|
||||
|
||||
#################
|
||||
# build the entry
|
||||
#################
|
||||
#
|
||||
all: ${TARGET} ${DATA}
|
||||
@${TRUE}
|
||||
|
||||
prog: prog.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
# alternative executable
|
||||
#
|
||||
alt: ${ALT_TARGET}
|
||||
@${TRUE}
|
||||
|
||||
prog.orig: prog.orig.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
# data files
|
||||
#
|
||||
data: ${DATA}
|
||||
@${TRUE}
|
||||
|
||||
|
||||
###############
|
||||
# utility rules
|
||||
###############
|
||||
#
|
||||
everything: all alt
|
||||
|
||||
clean:
|
||||
${RM} -f ${OBJ} ${ALT_OBJ}
|
||||
|
||||
clobber: clean
|
||||
${RM} -f ${TARGET} ${ALT_TARGET}
|
||||
@-if [ -e sandwich ]; then \
|
||||
${RM} -f sandwich; \
|
||||
echo 'ate sandwich'; \
|
||||
fi
|
||||
|
||||
nuke: clobber
|
||||
@${TRUE}
|
||||
|
||||
dist_clean: nuke
|
||||
@${TRUE}
|
||||
|
||||
install:
|
||||
@echo "Surely you are performing, Dr. May!"
|
||||
@${TRUE}
|
||||
|
||||
# backwards compatibility
|
||||
#
|
||||
build: all
|
||||
@${TRUE}
|
||||
|
||||
|
||||
##################
|
||||
# 133t hacker rulz
|
||||
##################
|
||||
#
|
||||
love:
|
||||
@echo 'not war?'
|
||||
@${TRUE}
|
||||
|
||||
haste:
|
||||
$(MAKE) waste
|
||||
@${TRUE}
|
||||
|
||||
waste:
|
||||
@echo 'haste'
|
||||
@${TRUE}
|
||||
|
||||
make:
|
||||
@echo 'Attend a maker faire'
|
||||
@${TRUE}
|
||||
|
||||
easter_egg:
|
||||
@echo you expected to often mis-understand this $${RANDOM} magic
|
||||
@echo chongo '<was here>' "/\\oo/\\"
|
||||
@echo Eggy
|
||||
|
||||
fabricate fashion form frame manufacture produce: make
|
||||
@${TRUE}
|
||||
|
||||
sandwich:
|
||||
@if [ `id -u` -eq 0 ]; then \
|
||||
echo 'Okay.'; \
|
||||
echo $${RANDOM}`date +%s`$${RANDOM} > $@; \
|
||||
else \
|
||||
echo 'What? Make it yourself.'; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
# Understand the history of the Homebrew Computer Club
|
||||
# as well as the West Coast Computer Faire and
|
||||
# you might be confused different. :-)
|
||||
#
|
||||
supernova: nuke
|
||||
@-if [ -r .code_anal ]; then \
|
||||
${RM} -f .code_anal_v6; \
|
||||
else \
|
||||
echo "planet deniers, like some members of the IAU, are so cute when they try to defend their logic"; \
|
||||
fi
|
||||
@echo A $@ helps ${MAKE} the elements that help form planets
|
||||
@${TRUE}
|
||||
|
||||
deep_magic:
|
||||
@-if [ -r .code_anal ]; then \
|
||||
ccode_analysis --deep_magic 3a3fabb90892eeb2f610ae0f74a35a970060665a063ab702bd686c17c4ae07f6 --FNV1a_hash_256_bit "prog"; \
|
||||
else \
|
||||
echo "Wrong! Do it again!"; \
|
||||
sleep 2; \
|
||||
echo "Wrong! Do it again!"; \
|
||||
sleep 2; \
|
||||
echo "Wrong! Do it again!"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
|
||||
magic: deep_magic
|
||||
@-if [ -r .code_anal ]; then \
|
||||
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_256_bit "prog"; \
|
||||
else \
|
||||
echo "If you don't eat yer meat, you can't have any pudding!"; \
|
||||
echo "How can you have any pudding if you don't eat yer meat?!"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
|
||||
# The IOCCC resident astronomer states
|
||||
#
|
||||
charon: supernova
|
||||
@echo $@ is a dwarf planet
|
||||
@echo dwarf is a type of planet
|
||||
@echo $@ is a planet
|
||||
|
||||
pluto: supernova
|
||||
${MAKE} charon
|
||||
@echo $@ is a dwarf planet
|
||||
@echo dwarf is a type of planet
|
||||
@echo $@ is a planet
|
||||
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
|
||||
@@ -0,0 +1,162 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
|
||||
<link rel="stylesheet"
|
||||
type="text/css"
|
||||
href="../hint.css">
|
||||
<title>Most cacophonic</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Most cacophonic</h1>
|
||||
|
||||
<p>Anton Älgmyr<br>
|
||||
Twitter: @aalgmyr</p>
|
||||
|
||||
<h2>Judges' comments:</h2>
|
||||
|
||||
<h3>To use:</h3>
|
||||
|
||||
<pre><code>make
|
||||
|
||||
cat prog.c | ./prog # Printing garbage might break your font
|
||||
./prog <file1> <file2> > out.raw
|
||||
./prog -d 2 0 out.raw # Decode the first (0th) channel out of two
|
||||
</code></pre>
|
||||
|
||||
<h3>To try:</h3>
|
||||
|
||||
<pre><code>./prog -h | ./prog -d 1 0
|
||||
|
||||
# Who needs cat?
|
||||
./prog prog.c | ./prog -d 1 0
|
||||
|
||||
# Assuming ALSA
|
||||
echo '<<<<<< /\_/\_/\ _-_-_-_ !!!!! :.:.:.: >>>>>> ****** ~~~~~~~' |
|
||||
./prog | aplay -c1 -fFLOAT_LE -r44100
|
||||
|
||||
# Assuming sox
|
||||
echo -n ' MENE MENE TEKEL UPHARSIN ' | ./prog |
|
||||
sox -t raw -c 1 -r 44100 -L -e floating-point -b 32 - -n spectrogram -d 10 -X 300
|
||||
</code></pre>
|
||||
|
||||
<h3>Selected Judges Remarks:</h3>
|
||||
|
||||
<p>Be warned, this is not your garden variety text-to-speech program! Earplugs are advised,
|
||||
or at least a handy and well-tested volume knob.</p>
|
||||
|
||||
<p>Pixels are numbered, amplitudes are weighed, frequencies are divided,
|
||||
and the message can be displayed in fiery letters, but don’t be alarmed.</p>
|
||||
|
||||
<p>How does decoding of the waveform work? Can you encode an arbitrary text in a sound sample?</p>
|
||||
|
||||
<h2>Author’s comments:</h2>
|
||||
|
||||
<h1>What is this?</h1>
|
||||
|
||||
<p>To put it brief, this entry is akin to a sound based cat. It takes characters as input and outputs them into frequency space as audio. The entry also supports decoding the produced waveforms using the <code>-d</code> flag. Usage instructions is output if run with the <code>-h</code> flag, albeit not in an immediately legible format.</p>
|
||||
|
||||
<h2>Details</h2>
|
||||
|
||||
<p>In normal operation, the entry reads characters from one or more sources. If the <code>-h</code> flag is given, usage instructions is used as a source. Else if file paths are present as arguments those will be used. Else stdin is used.</p>
|
||||
|
||||
<p>If a character is part of the supported subset of ASCII <code>{10, 32-126}</code> then that character is output into frequency space of an audio signal (44.1 kHz single precision float, endianness should depend on system endianness) through stdout. Any other character will be interpreted and outputted as a space.</p>
|
||||
|
||||
<p>Characters are printed using a (slightly modified) pixel font based on <a href="https://github.com/hchargois/gohufont">gohufont</a>. Pixels are drawn using crosses in frequency space, achieved by simultaneous up and down chirps.</p>
|
||||
|
||||
<p>Each input source is designated its own channel in the output (one float per channel per time step in the output) so if you have a surround sound system you could listen to a cacophony of chirpy characters.</p>
|
||||
|
||||
<p>Interestingly, with training you might actually be able to tell characters just from hearing. But even without training you can easily read along with the printed characters and have the sound make sense with the look of the characters.</p>
|
||||
|
||||
<p>See image spoiler.png for an example spectrogram.</p>
|
||||
|
||||
<h2>Limitations</h2>
|
||||
|
||||
<p>There is no error checking done when opening files, so expect segfaults if you provide the wrong path to a file.</p>
|
||||
|
||||
<p>This program is bound to misbehave if int is less than 32 bits.</p>
|
||||
|
||||
<p>Flags will only be interpreted correctly if they are the first argument. Reading a file named <code>-d</code> or <code>-h</code> is fully possible if it is not the first file provided, even though I am not sure why you would want to do that.</p>
|
||||
|
||||
<p>Providing invalid/unexpected arguments to the decode flag will result in odd behavior. Some erroneous arguments cause segfaults (negative number of channels, channel id outside valid range). One argument in particular causes an infinite loop printing whitespace.</p>
|
||||
|
||||
<h1>Techniques</h1>
|
||||
|
||||
<h2>Obfuscation</h2>
|
||||
|
||||
<p>A lot of the obfuscations done came naturally from trying to appease the size tool. To name some:</p>
|
||||
|
||||
<ul>
|
||||
<li>One character names</li>
|
||||
<li>Merging of related (and not so related) arithmetic operations</li>
|
||||
<li>Short circuiting for flow control to replace some <code>if</code>s</li>
|
||||
<li>Some <code>#defines</code>, sadly</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>On the intersection of size and obfuscation is the data encoding, which was quite fun to design.</p>
|
||||
|
||||
<p>Some additional obfuscation was done to mathematical formulas. Somewhat known expressions was transformed into equivalent but less recognizable counterparts.</p>
|
||||
|
||||
<p>I have tried to avoid intentional red herrings in the code, although fishy statements are plentiful.</p>
|
||||
|
||||
<h2>Data encoding</h2>
|
||||
|
||||
<p>The large string in the beginning of the source file contains font data, encoded in base64 using characters in the range <code>' '</code> to <code>'_'</code>. The space was chosen as the zero because the data contains a lot of zeroes, and quite helpfully the size tool ignores whitespace even in strings. Without this fact the program would have been too large and the decoding feature would have had to go. Fortunately this hole in the size spec was readily available. :)</p>
|
||||
|
||||
<p>Characters in the font (5x8 pixels, 40 bits) is packed into 7 base64 digits (which was a pain to decode in minimal code).</p>
|
||||
|
||||
<h2>Math</h2>
|
||||
|
||||
<p>Note that even though floats are used for the waveforms, the standard math library is not used at all! Most arithmetic is done purely on integers. The only major exception is generating a table of sine values which are interpolated to give high resolution waveforms. Can you see when the generation is triggered, and how it is done?</p>
|
||||
|
||||
<p>A critical issue encountered was that having abrupt starts and ends of signals cause a lot of problems with spectral leakage which makes spectrograms hard to read and audio painful to listen to. To reduce spectral leakage a windowing function was used. Although the one used is quite well known, it is not in a form that should be familiar to anyone. What looks like a polynomial and quacks like a polynomial might not actually be a polynomial, at least not deep inside.</p>
|
||||
|
||||
<h2>Printing a string</h2>
|
||||
|
||||
<p>The program was written to deal exclusively with file descriptors, so how would one go about printing a char array not from a file descriptor without adding additional logic? Answer: <code>ungetc</code> into stdin, one char at a time (to be standards compliant). This is used to print the usage instructions.</p>
|
||||
|
||||
<h1>Compilation warnings</h1>
|
||||
|
||||
<p>Compiling using</p>
|
||||
|
||||
<pre><code>gcc -Wall -Wextra -pedantic
|
||||
</code></pre>
|
||||
|
||||
<p>gives only <code>-Wmisleading-indentation</code> which is sensible considering the source code. While</p>
|
||||
|
||||
<pre><code>clang -Wall -Wextra -pedantic
|
||||
</code></pre>
|
||||
|
||||
<p>is a bit more pessimistic and gives <code>-Wempty-body</code> (I like loops without bodies), <code>-Wstring-plus-int</code> (since apparently some people think string+int is a concatenation) and one of the weirder warnings I have seen from me splitting a negative constant with whitespace. Compiling using</p>
|
||||
|
||||
<pre><code>clang -Wall -Wextra -pedantic -Weverything
|
||||
</code></pre>
|
||||
|
||||
<p>produces a few pagefuls of warnings and makes me feel generally bad about myself. :(</p>
|
||||
|
||||
<h1>Misc</h1>
|
||||
|
||||
<p>The reported size of the source code using the size tool is very intentionally 2018.</p>
|
||||
|
||||
<hr />
|
||||
|
||||
<!--
|
||||
(c) Copyright 1984-2018, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
|
||||
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
|
||||
|
||||
[judges]: http://www.ioccc.org/judges.html
|
||||
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
-->
|
||||
|
||||
<TABLE><TR>
|
||||
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
|
||||
<TD><P>© Copyright 1984-2018,
|
||||
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
|
||||
- All rights reserved<BR>
|
||||
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
|
||||
<TD> <!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
|
||||
</TR></TABLE>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,135 @@
|
||||
# Most cacophonic
|
||||
|
||||
Anton Älgmyr
|
||||
Twitter: @aalgmyr
|
||||
|
||||
|
||||
## Judges' comments:
|
||||
### To use:
|
||||
|
||||
make
|
||||
|
||||
cat prog.c | ./prog # Printing garbage might break your font
|
||||
./prog <file1> <file2> > out.raw
|
||||
./prog -d 2 0 out.raw # Decode the first (0th) channel out of two
|
||||
|
||||
### To try:
|
||||
|
||||
./prog -h | ./prog -d 1 0
|
||||
|
||||
# Who needs cat?
|
||||
./prog prog.c | ./prog -d 1 0
|
||||
|
||||
# Assuming ALSA
|
||||
echo '<<<<<< /\_/\_/\ _-_-_-_ !!!!! :.:.:.: >>>>>> ****** ~~~~~~~' |
|
||||
./prog | aplay -c1 -fFLOAT_LE -r44100
|
||||
|
||||
# Assuming sox
|
||||
echo -n ' MENE MENE TEKEL UPHARSIN ' | ./prog |
|
||||
sox -t raw -c 1 -r 44100 -L -e floating-point -b 32 - -n spectrogram -d 10 -X 300
|
||||
|
||||
### Selected Judges Remarks:
|
||||
|
||||
Be warned, this is not your garden variety text-to-speech program! Earplugs are advised,
|
||||
or at least a handy and well-tested volume knob.
|
||||
|
||||
Pixels are numbered, amplitudes are weighed, frequencies are divided,
|
||||
and the message can be displayed in fiery letters, but don't be alarmed.
|
||||
|
||||
How does decoding of the waveform work? Can you encode an arbitrary text in a sound sample?
|
||||
|
||||
|
||||
## Author's comments:
|
||||
|
||||
What is this?
|
||||
=============
|
||||
To put it brief, this entry is akin to a sound based cat. It takes characters as input and outputs them into frequency space as audio. The entry also supports decoding the produced waveforms using the `-d` flag. Usage instructions is output if run with the `-h` flag, albeit not in an immediately legible format.
|
||||
|
||||
Details
|
||||
-------
|
||||
In normal operation, the entry reads characters from one or more sources. If the `-h` flag is given, usage instructions is used as a source. Else if file paths are present as arguments those will be used. Else stdin is used.
|
||||
|
||||
If a character is part of the supported subset of ASCII `{10, 32-126}` then that character is output into frequency space of an audio signal (44.1 kHz single precision float, endianness should depend on system endianness) through stdout. Any other character will be interpreted and outputted as a space.
|
||||
|
||||
Characters are printed using a (slightly modified) pixel font based on [gohufont](https://github.com/hchargois/gohufont). Pixels are drawn using crosses in frequency space, achieved by simultaneous up and down chirps.
|
||||
|
||||
Each input source is designated its own channel in the output (one float per channel per time step in the output) so if you have a surround sound system you could listen to a cacophony of chirpy characters.
|
||||
|
||||
Interestingly, with training you might actually be able to tell characters just from hearing. But even without training you can easily read along with the printed characters and have the sound make sense with the look of the characters.
|
||||
|
||||
See image spoiler.png for an example spectrogram.
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
There is no error checking done when opening files, so expect segfaults if you provide the wrong path to a file.
|
||||
|
||||
This program is bound to misbehave if int is less than 32 bits.
|
||||
|
||||
Flags will only be interpreted correctly if they are the first argument. Reading a file named `-d` or `-h` is fully possible if it is not the first file provided, even though I am not sure why you would want to do that.
|
||||
|
||||
Providing invalid/unexpected arguments to the decode flag will result in odd behavior. Some erroneous arguments cause segfaults (negative number of channels, channel id outside valid range). One argument in particular causes an infinite loop printing whitespace.
|
||||
|
||||
Techniques
|
||||
==========
|
||||
|
||||
Obfuscation
|
||||
-----------
|
||||
A lot of the obfuscations done came naturally from trying to appease the size tool. To name some:
|
||||
|
||||
* One character names
|
||||
* Merging of related (and not so related) arithmetic operations
|
||||
* Short circuiting for flow control to replace some `if`s
|
||||
* Some `#defines`, sadly
|
||||
|
||||
On the intersection of size and obfuscation is the data encoding, which was quite fun to design.
|
||||
|
||||
Some additional obfuscation was done to mathematical formulas. Somewhat known expressions was transformed into equivalent but less recognizable counterparts.
|
||||
|
||||
I have tried to avoid intentional red herrings in the code, although fishy statements are plentiful.
|
||||
|
||||
|
||||
Data encoding
|
||||
-------------
|
||||
The large string in the beginning of the source file contains font data, encoded in base64 using characters in the range `' '` to `'_'`. The space was chosen as the zero because the data contains a lot of zeroes, and quite helpfully the size tool ignores whitespace even in strings. Without this fact the program would have been too large and the decoding feature would have had to go. Fortunately this hole in the size spec was readily available. :)
|
||||
|
||||
Characters in the font (5x8 pixels, 40 bits) is packed into 7 base64 digits (which was a pain to decode in minimal code).
|
||||
|
||||
Math
|
||||
----
|
||||
Note that even though floats are used for the waveforms, the standard math library is not used at all! Most arithmetic is done purely on integers. The only major exception is generating a table of sine values which are interpolated to give high resolution waveforms. Can you see when the generation is triggered, and how it is done?
|
||||
|
||||
A critical issue encountered was that having abrupt starts and ends of signals cause a lot of problems with spectral leakage which makes spectrograms hard to read and audio painful to listen to. To reduce spectral leakage a windowing function was used. Although the one used is quite well known, it is not in a form that should be familiar to anyone. What looks like a polynomial and quacks like a polynomial might not actually be a polynomial, at least not deep inside.
|
||||
|
||||
Printing a string
|
||||
-----------------
|
||||
The program was written to deal exclusively with file descriptors, so how would one go about printing a char array not from a file descriptor without adding additional logic? Answer: `ungetc` into stdin, one char at a time (to be standards compliant). This is used to print the usage instructions.
|
||||
|
||||
Compilation warnings
|
||||
====================
|
||||
Compiling using
|
||||
|
||||
gcc -Wall -Wextra -pedantic
|
||||
|
||||
gives only `-Wmisleading-indentation` which is sensible considering the source code. While
|
||||
|
||||
clang -Wall -Wextra -pedantic
|
||||
|
||||
is a bit more pessimistic and gives `-Wempty-body` (I like loops without bodies), `-Wstring-plus-int` (since apparently some people think string+int is a concatenation) and one of the weirder warnings I have seen from me splitting a negative constant with whitespace. Compiling using
|
||||
|
||||
clang -Wall -Wextra -pedantic -Weverything
|
||||
|
||||
produces a few pagefuls of warnings and makes me feel generally bad about myself. :(
|
||||
|
||||
Misc
|
||||
====
|
||||
The reported size of the source code using the size tool is very intentionally 2018.
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
<!--
|
||||
(c) Copyright 1984-2018, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
|
||||
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
|
||||
|
||||
[judges]: http://www.ioccc.org/judges.html
|
||||
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
-->
|
||||
@@ -0,0 +1,66 @@
|
||||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#define M malloc(sizeof(
|
||||
#define R fread(x,sizeof(float),Z*w,f)
|
||||
#define E free(
|
||||
|
||||
char*G=
|
||||
" "
|
||||
" '"
|
||||
"@(*AP( "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" _"
|
||||
"0 #@ . \"C^*/XH\"Q2_U(D&(5*E0C 4B54DV X \"!9A@ 89H$ !"
|
||||
"0(/@@4 @(/@@( #@T @(\" @( P, , P# , #Y1244^ ?R 0#%)14,A#9)24$B 1"
|
||||
"_)!0,$Y145%R Y145$^&!81T! #9)24DV#Y)24DP ;&P -C4 $$B% @ !04%!04 @4(D$ #!(1"
|
||||
"4 @#U574$^'^0D)!_&Z1D9'_$*!@8%^'Z!@8'_(&1D9'_(\"0D)#_%Z1D8%^/\\0$!#_ \"!_X$ /X! 0"
|
||||
"$&(-$*!#_ $! 0'_/] ,$#_/\\&&&#_'Z!@8%^&\"0D)#_'V\"A8%^&>8D)#_$Z1D9%B(\" _X\" /X"
|
||||
"! 0'^/ , PSP/P#' /\\,<H$\"C', @'R# ,&AD8F'(&!_P ,,,, _X&!! @0\" 0 "
|
||||
"$! 0$! @0( \\5%14\" X1$0G_!$1$1$./\\2$1$. T5%14. \"0D'\\ 'Y)"
|
||||
"144X \\0$ C_ !7Q 7A$! $2# 3_ $!_H \\0'Q ? \\0"
|
||||
"$! ? X1$1$.#A$1\"1_'](1$0X @0$ @? (5%14)"
|
||||
" 1$?X0!\\\" 0$>!@& 088!X!#@$>"
|
||||
"!$*! H1#X)!04X!$9%1,1"
|
||||
"(&!;A 0 _P "
|
||||
" ! 0;H&!"
|
||||
" @$\""
|
||||
"! ("
|
||||
"\0"; int s,p,e,c,t,r,a,l; /* l e a k a g e */
|
||||
|
||||
int
|
||||
F(int o
|
||||
,int n, int t
|
||||
){char*p=(o*(136-o)
|
||||
>=1260)*7*(o-9)+G; for(
|
||||
n=!(o=-1); n=*p+++64*n-*G
|
||||
,(o+=3)>>2<5-t; ); return 255
|
||||
&n>>2*o%8; } float L[0x400];int
|
||||
T(float a,float b,float l,float*e)
|
||||
{return L[0x3ff]||!(e[1]=b*a+l**e)||
|
||||
!T(l*a-b**e,b,l,e+1); } float f(int x)
|
||||
{int w=s<<!!T(1,6.135885e-3,-1.882472e-5
|
||||
+1,L); x=(x%w+w)%w<<9; return(L[x/s]*(s-x%
|
||||
s)+L[x/s+1]*(x%s))/s; } int C(float*h,float*
|
||||
i,int r,int P){ int x,y,c; for(y=0; h<i; ++y,h
|
||||
+=r){ c=P<1; for(*h=x=0; x<8; c+=(1&P>>x&&P+(*
|
||||
h+=f(e*(l+a*(2*x+1))*y)*f(s/2-e*a*y+e*a*y*y*(t/p
|
||||
)/(s/p)))),++x); float z=f(y*t)*f(y*t); *h=z*(1+3*
|
||||
z+2*z*z)/6**h/c; } return h-i-r+1; } void d(int w,
|
||||
int n,FILE*f){int Z=s/t; int S[5]; float**P=M float*
|
||||
)*c);for(r=0;r<c;++r){ P[r]=M float)*Z); C(P[r],P[r]
|
||||
+Z,1,r); } float*x=M float)*Z*w); for (; ; ){ for(r=0;
|
||||
r<5 ; ++r){ int o=1; for(R,a=256; o&&--a; )for(o=t=0; t<Z; o+=
|
||||
P[a][ t]!=x[w*t+n],++t); S[r]=a; } if(R-Z*w)break; for(r=a= - 12;r<
|
||||
5&&(a+= a<11?22:1)<127; )for(r=-1; ++r<5&&F(a,1,r)==S[r]; );if(a <127&&r
|
||||
==5 )putchar( a); } for(; --c; E P[c])); E P); fclose(f);}int main(int q,char**v) {s=
|
||||
44100 ;p=25; e= 55;c=256; t=75; r=q>1?v[1][0]*c+v[1][1]:0; a=7;l=16;if(r ==11620){d (atoi
|
||||
(v[2]), atoi(v[3]), q<5?stdin:fopen(v[4],"r")); return 0; } char*H=malloc(c),* h=H; sprintf (H,"\0"
|
||||
"Usage\n" " %s [-" "h] [-d #c cid] file1 file2 ... (or stdin)"+(q-1&&r==11624 ),v[0]);if(* H)q=1;int
|
||||
w=2>q?1:q -1; FILE**f=M FILE*)*w); f[0]=stdin; if(q>1)for(r=0; r<w; f[r]=fopen(v[r +1],"r"),++r); int l=s/t
|
||||
*w; float *b=M float)*l ),*t=b+l; int*i=M int)*w); for(; ; ){ int x=*h&&1>ungetc(* H++,*f); for(r =w; r--;)
|
||||
{ i[r]=getc (f[r]); if(i[r]<0)i[r]=!++x; } if(x==w)break; while(++r<6){ while(C(b++,t,w,F(*i++,r< 5,r))); i-=
|
||||
w; fwrite(b-=w,sizeof(float),l,stdout); } fflush(stdout); } while(fclose(f[--w]),w); E f); E b); E i); E h);}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#define M malloc(sizeof(
|
||||
#define R fread(x,sizeof(float),Z*w,f)
|
||||
#define E free(
|
||||
|
||||
char*G=
|
||||
" "
|
||||
" '"
|
||||
"@(*AP( "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" _"
|
||||
"0 #@ . \"C^*/XH\"Q2_U(D&(5*E0C 4B54DV X \"!9A@ 89H$ !"
|
||||
"0(/@@4 @(/@@( #@T @(\" @( P, , P# , #Y1244^ ?R 0#%)14,A#9)24$B 1"
|
||||
"_)!0,$Y145%R Y145$^&!81T! #9)24DV#Y)24DP ;&P -C4 $$B% @ !04%!04 @4(D$ #!(1"
|
||||
"4 @#U574$^'^0D)!_&Z1D9'_$*!@8%^'Z!@8'_(&1D9'_(\"0D)#_%Z1D8%^/\\0$!#_ \"!_X$ /X! 0"
|
||||
"$&(-$*!#_ $! 0'_/] ,$#_/\\&&&#_'Z!@8%^&\"0D)#_'V\"A8%^&>8D)#_$Z1D9%B(\" _X\" /X"
|
||||
"! 0'^/ , PSP/P#' /\\,<H$\"C', @'R# ,&AD8F'(&!_P ,,,, _X&!! @0\" 0 "
|
||||
"$! 0$! @0( \\5%14\" X1$0G_!$1$1$./\\2$1$. T5%14. \"0D'\\ 'Y)"
|
||||
"144X \\0$ C_ !7Q 7A$! $2# 3_ $!_H \\0'Q ? \\0"
|
||||
"$! ? X1$1$.#A$1\"1_'](1$0X @0$ @? (5%14)"
|
||||
" 1$?X0!\\\" 0$>!@& 088!X!#@$>"
|
||||
"!$*! H1#X)!04X!$9%1,1"
|
||||
"(&!;A 0 _P "
|
||||
" ! 0;H&!"
|
||||
" @$\""
|
||||
"! ("
|
||||
"\0"; int s,p,e,c,t,r,a,l; /* l e a k a g e */
|
||||
|
||||
int
|
||||
F(int o
|
||||
,int n, int t
|
||||
){char*p=(o*(136-o)
|
||||
>=1260)*7*(o-9)+G; for(
|
||||
n=!(o=-1); n=*p+++64*n-*G
|
||||
,(o+=3)>>2<5-t; ); return 255
|
||||
&n>>2*o%8; } float L[0x400];int
|
||||
T(float a,float b,float l,float*e)
|
||||
{return L[0x3ff]||!(e[1]=b*a+l**e)||
|
||||
!T(l*a-b**e,b,l,e+1); } float f(int x)
|
||||
{int w=s<<!!T(1,6.135885e-3,-1.882472e-5
|
||||
+1,L); x=(x%w+w)%w<<9; return(L[x/s]*(s-x%
|
||||
s)+L[x/s+1]*(x%s))/s; } int C(float*h,float*
|
||||
i,int r,int P){ int x,y,c; for(y=0; h<i; ++y,h
|
||||
+=r){ c=P<1; for(*h=x=0; x<8; c+=(1&P>>x&&P+(*
|
||||
h+=f(e*(l+a*(2*x+1))*y)*f(s/2-e*a*y+e*a*y*y*(t/p
|
||||
)/(s/p)))),++x); float z=f(y*t)*f(y*t); *h=z*(1+3*
|
||||
z+2*z*z)/6**h/c; } return h-i-r+1; } void d(int w,
|
||||
int n,FILE*f){int Z=s/t; int S[5]; float**P=M float*
|
||||
)*c);for(r=0;r<c;++r){ P[r]=M float)*Z); C(P[r],P[r]
|
||||
+Z,1,r); } float*x=M float)*Z*w); for (; ; ){ for(r=0;
|
||||
r<5 ; ++r){ int o=1; for(R,a=256; o&&--a; )for(o=t=0; t<Z; o+=
|
||||
P[a][ t]!=x[w*t+n],++t); S[r]=a; } if(R-Z*w)break; for(r=a=- 12;r<
|
||||
5&&(a+= a<11?22:1)<127; )for(r=-1; ++r<5&&F(a,1,r)==S[r]; );if(a <127&&r
|
||||
==5 )putchar( a); } for(; --c; E P[c])); E P); fclose(f);}int main(int q,char**v) {s=
|
||||
44100 ;p=25; e= 55;c=256; t=75; r=q>1?v[1][0]*c+v[1][1]:0; a=7;l=16;if(r ==11620){d (atoi
|
||||
(v[2]), atoi(v[3]), q<5?stdin:fopen(v[4],"r")); return 0; } char*H=malloc(c),* h=H; sprintf (H,"\0"
|
||||
"Usage\n" " %s [-" "h] [-d #c cid] file1 file2 ... (or stdin)"+(q-1&&r==11624 ),v[0]);if(* H)q=1;int
|
||||
w=2>q?1:q -1; FILE**f=M FILE*)*w); f[0]=stdin; if(q>1)for(r=0; r<w; f[r]=fopen(v[r +1],"r"),++r); int l=s/t
|
||||
*w; float *b=M float)*l ),*t=b+l; int*i=M int)*w); for(; ; ){ int x=*h&&1>ungetc(* H++,*f); for(r =w; r--;)
|
||||
{ i[r]=getc (f[r]); if(i[r]<0)i[r]=!++x; } if(x==w)break; while(++r<6){ while(C(b++,t,w,F(*i++,r< 5,r))); i-=
|
||||
w; fwrite(b-=w,sizeof(float),l,stdout); } fflush(stdout); } while(fclose(f[--w]),w); E f); E b); E i); E h);}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
@@ -0,0 +1,286 @@
|
||||
#!/usr/bin/env make
|
||||
#
|
||||
# 2018 makefile
|
||||
#
|
||||
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
|
||||
# is licensed under:
|
||||
#
|
||||
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
|
||||
#
|
||||
# See: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
|
||||
################
|
||||
# tool locations
|
||||
################
|
||||
#
|
||||
SHELL= /bin/bash
|
||||
CP= cp
|
||||
CPP= cpp
|
||||
GUNZIP= gunzip
|
||||
BUNZIP2= bunzip2
|
||||
GZIP_PROG= gzip
|
||||
BZIP2= bzip2
|
||||
CURL= curl
|
||||
DD= dd
|
||||
LD= ld
|
||||
MAKE= make
|
||||
RM= rm
|
||||
SED= sed
|
||||
TAR= tar
|
||||
TRUE= true
|
||||
MKDIR= mkdir
|
||||
MV= mv
|
||||
TR= tr
|
||||
GREP= grep
|
||||
SORT= sort
|
||||
UNIQ= uniq
|
||||
|
||||
# Set X11_LIBDIR to the directory where the X11 library resides
|
||||
#
|
||||
#X11_LIBDIR= /usr/X11R6/lib
|
||||
#X11_LIBDIR= /usr/X11/lib
|
||||
X11_LIBDIR= /opt/X11/lib
|
||||
|
||||
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
|
||||
#
|
||||
#X11_INCDIR= /usr/X11R6/include
|
||||
#X11_INCDIR= /usr/X11/include
|
||||
X11_INCDIR= /opt/X11/include
|
||||
|
||||
# Compiler warnings
|
||||
#
|
||||
#CWARN=
|
||||
#CWARN= -Wall
|
||||
#CWARN= -Wall -Wextra
|
||||
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
|
||||
#CWARN= -Wall -Wextra -Weverything
|
||||
#CWARN= -Wall -Wextra -Weverything -pedantic
|
||||
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
|
||||
|
||||
# Silence warnings that ${CWARN} would normally complain about
|
||||
#
|
||||
CSILENCE=
|
||||
#CSILENCE= -Wno-implicit-int
|
||||
|
||||
# compiler standard
|
||||
#
|
||||
#CSTD=
|
||||
#CSTD= -ansi
|
||||
CSTD= -std=c11
|
||||
|
||||
# compiler bit architecture
|
||||
#
|
||||
# Some entries require 32-bitness:
|
||||
# ARCH= -m32
|
||||
#
|
||||
# Some entries require 64-bitness:
|
||||
# ARCH= -m64
|
||||
#
|
||||
# By default we assume nothing:
|
||||
#
|
||||
ARCH=
|
||||
|
||||
# defines that are needed to compile
|
||||
#
|
||||
CDEFINE=
|
||||
#CDEFINE= -DIOCCC=25
|
||||
|
||||
# include files that are needed to compile
|
||||
#
|
||||
CINCLUDE=
|
||||
#CINCLUDE= -include stdlib.h
|
||||
#CINCLUDE= -include stdio.h
|
||||
#CINCLUDE= -include stdlib.h -include stdio.h
|
||||
#CINCLUDE= -I ${X11_INCDIR}
|
||||
|
||||
# optimization
|
||||
#
|
||||
# Most compiles will safely use -O2. Some can use only -O1 or -O.
|
||||
# A few compilers have broken optimizers or this entry make break
|
||||
# under those buggy optimizers and thus you may not want anything.
|
||||
# Reasonable compilers will allow for -O3.
|
||||
#
|
||||
#OPT=
|
||||
#OPT= -O
|
||||
#OPT= -O1
|
||||
#OPT= -O2
|
||||
OPT= -O3
|
||||
|
||||
# default flags for ANSI C compilation
|
||||
#
|
||||
CFLAGS= ${CSTD} ${CWARN} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
|
||||
|
||||
# Libraries needed to build
|
||||
#
|
||||
LIBS=
|
||||
#LIBS= -L ${X11_LIBDIR}
|
||||
|
||||
# ANSI compiler
|
||||
#
|
||||
# Set CC to the name of your ANSI compiler.
|
||||
#
|
||||
# Some entries seem to need gcc. If you have gcc, set
|
||||
# both CC and MAY_NEED_GCC to gcc.
|
||||
#
|
||||
# If you do not have gcc, set CC to the name of your ANSI compiler, and
|
||||
# set MAY_NEED_GCC to either ${CC} (and hope for the best) or to just :
|
||||
# to disable such programs.
|
||||
#
|
||||
CC= cc
|
||||
#CC=clang
|
||||
MAY_NEED_GCC= gcc
|
||||
|
||||
|
||||
##############################
|
||||
# Special flags for this entry
|
||||
##############################
|
||||
#
|
||||
OBJ= prog.o
|
||||
DATA=
|
||||
TARGET= prog
|
||||
#
|
||||
ALT_OBJ= prog.orig.o
|
||||
ALT_TARGET= prog.orig
|
||||
|
||||
|
||||
#################
|
||||
# build the entry
|
||||
#################
|
||||
#
|
||||
all: ${TARGET} ${DATA}
|
||||
@${TRUE}
|
||||
|
||||
prog: prog.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
# alternative executable
|
||||
#
|
||||
alt: ${ALT_TARGET}
|
||||
@${TRUE}
|
||||
|
||||
prog.orig: prog.orig.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
# data files
|
||||
#
|
||||
data: ${DATA}
|
||||
@${TRUE}
|
||||
|
||||
|
||||
###############
|
||||
# utility rules
|
||||
###############
|
||||
#
|
||||
everything: all alt
|
||||
|
||||
clean:
|
||||
${RM} -f ${OBJ} ${ALT_OBJ}
|
||||
|
||||
clobber: clean
|
||||
${RM} -f ${TARGET} ${ALT_TARGET}
|
||||
@-if [ -e sandwich ]; then \
|
||||
${RM} -f sandwich; \
|
||||
echo 'ate sandwich'; \
|
||||
fi
|
||||
|
||||
nuke: clobber
|
||||
@${TRUE}
|
||||
|
||||
dist_clean: nuke
|
||||
@${TRUE}
|
||||
|
||||
install:
|
||||
@echo "Surely you are performing, Dr. May!"
|
||||
@${TRUE}
|
||||
|
||||
# backwards compatibility
|
||||
#
|
||||
build: all
|
||||
@${TRUE}
|
||||
|
||||
|
||||
##################
|
||||
# 133t hacker rulz
|
||||
##################
|
||||
#
|
||||
love:
|
||||
@echo 'not war?'
|
||||
@${TRUE}
|
||||
|
||||
haste:
|
||||
$(MAKE) waste
|
||||
@${TRUE}
|
||||
|
||||
waste:
|
||||
@echo 'haste'
|
||||
@${TRUE}
|
||||
|
||||
make:
|
||||
@echo 'Attend a maker faire'
|
||||
@${TRUE}
|
||||
|
||||
easter_egg:
|
||||
@echo you expected to often mis-understand this $${RANDOM} magic
|
||||
@echo chongo '<was here>' "/\\oo/\\"
|
||||
@echo Eggy
|
||||
|
||||
fabricate fashion form frame manufacture produce: make
|
||||
@${TRUE}
|
||||
|
||||
sandwich:
|
||||
@if [ `id -u` -eq 0 ]; then \
|
||||
echo 'Okay.'; \
|
||||
echo $${RANDOM}`date +%s`$${RANDOM} > $@; \
|
||||
else \
|
||||
echo 'What? Make it yourself.'; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
# Understand the history of the Homebrew Computer Club
|
||||
# as well as the West Coast Computer Faire and
|
||||
# you might be confused different. :-)
|
||||
#
|
||||
supernova: nuke
|
||||
@-if [ -r .code_anal ]; then \
|
||||
${RM} -f .code_anal_v6; \
|
||||
else \
|
||||
echo "planet deniers, like some members of the IAU, are so cute when they try to defend their logic"; \
|
||||
fi
|
||||
@echo A $@ helps ${MAKE} the elements that help form planets
|
||||
@${TRUE}
|
||||
|
||||
deep_magic:
|
||||
@-if [ -r .code_anal ]; then \
|
||||
ccode_analysis --deep_magic 3a3fabb90892eeb2f610ae0f74a35a970060665a063ab702bd686c17c4ae07f6 --FNV1a_hash_256_bit "prog"; \
|
||||
else \
|
||||
echo "Wrong! Do it again!"; \
|
||||
sleep 2; \
|
||||
echo "Wrong! Do it again!"; \
|
||||
sleep 2; \
|
||||
echo "Wrong! Do it again!"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
|
||||
magic: deep_magic
|
||||
@-if [ -r .code_anal ]; then \
|
||||
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_256_bit "prog"; \
|
||||
else \
|
||||
echo "If you don't eat yer meat, you can't have any pudding!"; \
|
||||
echo "How can you have any pudding if you don't eat yer meat?!"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
|
||||
# The IOCCC resident astronomer states
|
||||
#
|
||||
charon: supernova
|
||||
@echo $@ is a dwarf planet
|
||||
@echo dwarf is a type of planet
|
||||
@echo $@ is a planet
|
||||
|
||||
pluto: supernova
|
||||
${MAKE} charon
|
||||
@echo $@ is a dwarf planet
|
||||
@echo dwarf is a type of planet
|
||||
@echo $@ is a planet
|
||||
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
|
||||
@@ -0,0 +1,99 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
|
||||
<link rel="stylesheet"
|
||||
type="text/css"
|
||||
href="../hint.css">
|
||||
<title>Most able to divine code gaps</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Most able to divine code gaps</h1>
|
||||
|
||||
<p>Derek Anderson</p>
|
||||
|
||||
<h2>Judges' comments:</h2>
|
||||
|
||||
<h3>To use:</h3>
|
||||
|
||||
<pre><code>make
|
||||
./prog < textfile
|
||||
</code></pre>
|
||||
|
||||
<h3>Try:</h3>
|
||||
|
||||
<pre><code>./prog < prog.c
|
||||
./prog < prog.orig.c
|
||||
./prog < hint.text
|
||||
</code></pre>
|
||||
|
||||
<h3>Selected Judges Remarks:</h3>
|
||||
|
||||
<p>With this entry, you won’t need to turn your monitor <a href="http://en.wikipedia.org/wiki/River_%28typography%29">upside down</a>!</p>
|
||||
|
||||
<p>Compare <code>prog.c</code> and <code>prog.orig.c</code> and find out why we had to modify the entry, and what confused the author
|
||||
(see the author’s remarks). No, it was not the shape of the Roman V that we, or the compiler, didn’t like.</p>
|
||||
|
||||
<h2>Author’s comments:</h2>
|
||||
|
||||
<h2>Compiling the program</h2>
|
||||
|
||||
<pre><code>gcc -Wall -Wextra -Wpedantic -O3 -std=c11 prog.c -o prog
|
||||
</code></pre>
|
||||
|
||||
<p>Also works with a standard of c99, but c90/c89 will not compile due to
|
||||
for loop initial declarations, along with additional warnings about
|
||||
variable length arrays and lack of a return statement.</p>
|
||||
|
||||
<h2>Additional info</h2>
|
||||
|
||||
<p>This small program, when given text on stdin, will produce a pattern of
|
||||
squiggly lines. This pattern is deterministic, and it shouldn’t be too
|
||||
difficult to determine from whence they come. There is even a comment
|
||||
that describes the highlighted phenomena in the source, for those that
|
||||
require a small nudge. With denser text blocks, such as an essay or
|
||||
similar prose, the output can be rather pretty, in an chaotic emergence
|
||||
sort of way. Try using this file, or the source file as inputs.</p>
|
||||
|
||||
<p>In its current form, this program can handle lines of length 255; to
|
||||
adjust this limit, change the variable <code>a</code> at the top of the source.
|
||||
Other adjustments, such as the exact printed characters, are rather
|
||||
easy, once sufficient reverse engineering has occurred. Improvements
|
||||
such as proper handling of tabs are left as an exercise to the reader.</p>
|
||||
|
||||
<p>In developing this program, the author found a potentially interesting
|
||||
bug. If the expression <code>(j=k,j)</code> (near the middle of the source) is
|
||||
changed to <code>(j=k,k)</code>, the program produces different output. The author
|
||||
used compiler gcc 5.4.0, compiled for x86_64-linux-gnu. Enabling or
|
||||
disabling optimization produces the same results. The author is not
|
||||
sure who is the culprit, but instead shrugged and moved on with life.
|
||||
Of course, YMMV with your own environment.</p>
|
||||
|
||||
<p>The structure of this program, as you may have deduced, is two for
|
||||
loops, one nested in the other. There is also a bunch of direct
|
||||
variable assignment, such as <code>j=k</code>. There is some filler fluff, such as
|
||||
<code>0-0+0</code>, but all that sort should be rather easy to spot. It was mostly
|
||||
added for the purpose of making certain things line up right, and only
|
||||
secondarily to obfuscate.</p>
|
||||
|
||||
<hr />
|
||||
|
||||
<!--
|
||||
(c) Copyright 1984-2018, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
|
||||
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
|
||||
|
||||
[judges]: http://www.ioccc.org/judges.html
|
||||
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
-->
|
||||
|
||||
<TABLE><TR>
|
||||
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
|
||||
<TD><P>© Copyright 1984-2018,
|
||||
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
|
||||
- All rights reserved<BR>
|
||||
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
|
||||
<TD> <!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
|
||||
</TR></TABLE>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,73 @@
|
||||
# Most able to divine code gaps
|
||||
|
||||
Derek Anderson
|
||||
|
||||
|
||||
## Judges' comments:
|
||||
### To use:
|
||||
|
||||
make
|
||||
./prog < textfile
|
||||
|
||||
### Try:
|
||||
|
||||
./prog < prog.c
|
||||
./prog < prog.orig.c
|
||||
./prog < hint.text
|
||||
|
||||
### Selected Judges Remarks:
|
||||
|
||||
With this entry, you won't need to turn your monitor [upside down](http://en.wikipedia.org/wiki/River_%28typography%29)!
|
||||
|
||||
Compare `prog.c` and `prog.orig.c` and find out why we had to modify the entry, and what confused the author
|
||||
(see the author's remarks). No, it was not the shape of the Roman V that we, or the compiler, didn't like.
|
||||
|
||||
|
||||
## Author's comments:
|
||||
## Compiling the program
|
||||
|
||||
gcc -Wall -Wextra -Wpedantic -O3 -std=c11 prog.c -o prog
|
||||
|
||||
Also works with a standard of c99, but c90/c89 will not compile due to
|
||||
for loop initial declarations, along with additional warnings about
|
||||
variable length arrays and lack of a return statement.
|
||||
|
||||
## Additional info
|
||||
|
||||
This small program, when given text on stdin, will produce a pattern of
|
||||
squiggly lines. This pattern is deterministic, and it shouldn't be too
|
||||
difficult to determine from whence they come. There is even a comment
|
||||
that describes the highlighted phenomena in the source, for those that
|
||||
require a small nudge. With denser text blocks, such as an essay or
|
||||
similar prose, the output can be rather pretty, in an chaotic emergence
|
||||
sort of way. Try using this file, or the source file as inputs.
|
||||
|
||||
In its current form, this program can handle lines of length 255; to
|
||||
adjust this limit, change the variable `a` at the top of the source.
|
||||
Other adjustments, such as the exact printed characters, are rather
|
||||
easy, once sufficient reverse engineering has occurred. Improvements
|
||||
such as proper handling of tabs are left as an exercise to the reader.
|
||||
|
||||
In developing this program, the author found a potentially interesting
|
||||
bug. If the expression `(j=k,j)` (near the middle of the source) is
|
||||
changed to `(j=k,k)`, the program produces different output. The author
|
||||
used compiler gcc 5.4.0, compiled for x86_64-linux-gnu. Enabling or
|
||||
disabling optimization produces the same results. The author is not
|
||||
sure who is the culprit, but instead shrugged and moved on with life.
|
||||
Of course, YMMV with your own environment.
|
||||
|
||||
The structure of this program, as you may have deduced, is two for
|
||||
loops, one nested in the other. There is also a bunch of direct
|
||||
variable assignment, such as `j=k`. There is some filler fluff, such as
|
||||
`0-0+0`, but all that sort should be rather easy to spot. It was mostly
|
||||
added for the purpose of making certain things line up right, and only
|
||||
secondarily to obfuscate.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
<!--
|
||||
(c) Copyright 1984-2018, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
|
||||
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
|
||||
|
||||
[judges]: http://www.ioccc.org/judges.html
|
||||
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
-->
|
||||
@@ -0,0 +1,16 @@
|
||||
#include<stdio.h>
|
||||
int a = 256;int main(){for(char b[a+a+a],
|
||||
*c=b ,*d=b+ a ,*e=b+a+a,*f,*g=fgets(e,(b[
|
||||
a]=b [a+a] =a- a,a) , stdin);c[0]=a-a,f=c
|
||||
,c=d ,d=e ,e=f, f= g,g =0,g = fgets(e,a+a
|
||||
-a+ a -a+a -a+ a- +a,stdin ),f +a-a ; pu\
|
||||
tchar(+10)) { for( int h= 1,i=1,j, k=0 ,l
|
||||
=e[0]==32,m,n=0,o=c [ 0]== 32, p, q=0;d[q
|
||||
];j=k,k=l,m=n,n=o,p=(j)+(k* 2 )+(l =(i =
|
||||
e[ q]&&i ) &&e[q +1 ]== 32,l*4)+(m* 8 )+(
|
||||
16* n )+( o =(h =c[ q]&&h)&&c[q+1]==
|
||||
32,o* (16+16) )+0-0 +0, putchar(" ......"
|
||||
/*\ ( ||| ) |/|/ / */".')|)\\\\\\\\'"
|
||||
"" "|||" "|||" "|'" ")|)\\\\\\\\'/|/(/"
|
||||
"(/'/|/\\|\\|'/|/(/(/'/|/\\|\\|"[d[q++]==
|
||||
32?p:0]));}}/* typographic tributaries */
|
||||
@@ -0,0 +1,16 @@
|
||||
#include<stdio.h>
|
||||
int a = 256;int main(){for(char b[a+a+a],
|
||||
*c=b ,*d=b+ a ,*e=b+a+a,*f,*g=fgets(e,(b[
|
||||
a]=b [a+a] =a- a,a) , stdin);c[0]=a-a,f=c
|
||||
,c=d ,d=e ,e=f, f= g,g =g,g = fgets(e,a+a
|
||||
-a+ a -a+a -a+ a- +a,stdin ),f +a-a ; pu\
|
||||
tchar(+10)) { for( int h= 1,i=1,j, k=0 ,l
|
||||
=e[0]==32,m,n=0,o=c [ 0]== 32, p, q=0;d[q
|
||||
];p=(j=k,j)+(k=l,k*2)+(l=(i = i&&e [q] )
|
||||
&& e[q+1 ] ==32, l *4)+( m=n,m*8)+( n =o,
|
||||
16* n )+( o =(h =c[ q]&&h)&&c[q+1]==
|
||||
32,o* (16+16) )+0-0 +0, putchar(" ......"
|
||||
/*\ ( ||| ) |/|/ / */".')|)\\\\\\\\'"
|
||||
"" "|||" "|||" "|'" ")|)\\\\\\\\'/|/(/"
|
||||
"(/'/|/\\|\\|'/|/(/(/'/|/\\|\\|"[d[q++]==
|
||||
32?p:0]));}}/* typographic tributaries */
|
||||
@@ -0,0 +1,287 @@
|
||||
#!/usr/bin/env make
|
||||
#
|
||||
# 2018 makefile
|
||||
#
|
||||
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
|
||||
# is licensed under:
|
||||
#
|
||||
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
|
||||
#
|
||||
# See: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
|
||||
################
|
||||
# tool locations
|
||||
################
|
||||
#
|
||||
SHELL= /bin/bash
|
||||
CP= cp
|
||||
CPP= cpp
|
||||
GUNZIP= gunzip
|
||||
BUNZIP2= bunzip2
|
||||
GZIP_PROG= gzip
|
||||
BZIP2= bzip2
|
||||
CURL= curl
|
||||
DD= dd
|
||||
LD= ld
|
||||
MAKE= make
|
||||
RM= rm
|
||||
SED= sed
|
||||
TAR= tar
|
||||
TRUE= true
|
||||
MKDIR= mkdir
|
||||
MV= mv
|
||||
TR= tr
|
||||
GREP= grep
|
||||
SORT= sort
|
||||
UNIQ= uniq
|
||||
|
||||
# Set X11_LIBDIR to the directory where the X11 library resides
|
||||
#
|
||||
#X11_LIBDIR= /usr/X11R6/lib
|
||||
#X11_LIBDIR= /usr/X11/lib
|
||||
X11_LIBDIR= /opt/X11/lib
|
||||
|
||||
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
|
||||
#
|
||||
#X11_INCDIR= /usr/X11R6/include
|
||||
#X11_INCDIR= /usr/X11/include
|
||||
X11_INCDIR= /opt/X11/include
|
||||
|
||||
# Compiler warnings
|
||||
#
|
||||
#CWARN=
|
||||
#CWARN= -Wall
|
||||
#CWARN= -Wall -Wextra
|
||||
CWARN= -Wall -Wextra ${CSILENCE}
|
||||
#CWARN= -Wall -Wextra -pedantic ${CSILENCE}
|
||||
#CWARN= -Wall -Wextra -Weverything
|
||||
#CWARN= -Wall -Wextra -Weverything -pedantic
|
||||
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
|
||||
|
||||
# Silence warnings that ${CWARN} would normally complain about
|
||||
#
|
||||
#CSILENCE=
|
||||
CSILENCE= -Wno-implicit-int -Wno-parentheses -Wno-return-type
|
||||
|
||||
# compiler standard
|
||||
#
|
||||
#CSTD=
|
||||
#CSTD= -ansi
|
||||
CSTD= -std=c11
|
||||
|
||||
# compiler bit architecture
|
||||
#
|
||||
# Some entries require 32-bitness:
|
||||
# ARCH= -m32
|
||||
#
|
||||
# Some entries require 64-bitness:
|
||||
# ARCH= -m64
|
||||
#
|
||||
# By default we assume nothing:
|
||||
#
|
||||
ARCH=
|
||||
|
||||
# defines that are needed to compile
|
||||
#
|
||||
CDEFINE=
|
||||
#CDEFINE= -DIOCCC=25
|
||||
|
||||
# include files that are needed to compile
|
||||
#
|
||||
#CINCLUDE=
|
||||
#CINCLUDE= -include stdlib.h
|
||||
CINCLUDE= -include stdio.h
|
||||
#CINCLUDE= -include stdlib.h -include stdio.h
|
||||
#CINCLUDE= -I ${X11_INCDIR}
|
||||
|
||||
# optimization
|
||||
#
|
||||
# Most compiles will safely use -O2. Some can use only -O1 or -O.
|
||||
# A few compilers have broken optimizers or this entry make break
|
||||
# under those buggy optimizers and thus you may not want anything.
|
||||
# Reasonable compilers will allow for -O3.
|
||||
#
|
||||
#OPT=
|
||||
#OPT= -O
|
||||
#OPT= -O1
|
||||
#OPT= -O2
|
||||
OPT= -O3
|
||||
|
||||
# default flags for ANSI C compilation
|
||||
#
|
||||
CFLAGS= ${CSTD} ${CWARN} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
|
||||
|
||||
# Libraries needed to build
|
||||
#
|
||||
LIBS= -lm
|
||||
#LIBS= -L ${X11_LIBDIR}
|
||||
|
||||
# ANSI compiler
|
||||
#
|
||||
# Set CC to the name of your ANSI compiler.
|
||||
#
|
||||
# Some entries seem to need gcc. If you have gcc, set
|
||||
# both CC and MAY_NEED_GCC to gcc.
|
||||
#
|
||||
# If you do not have gcc, set CC to the name of your ANSI compiler, and
|
||||
# set MAY_NEED_GCC to either ${CC} (and hope for the best) or to just :
|
||||
# to disable such programs.
|
||||
#
|
||||
CC= cc
|
||||
#CC=clang
|
||||
MAY_NEED_GCC= gcc
|
||||
|
||||
|
||||
##############################
|
||||
# Special flags for this entry
|
||||
##############################
|
||||
#
|
||||
OBJ= prog.o
|
||||
DATA=
|
||||
TARGET= prog
|
||||
#
|
||||
ALT_OBJ=
|
||||
ALT_TARGET= prog.orig
|
||||
|
||||
|
||||
#################
|
||||
# build the entry
|
||||
#################
|
||||
#
|
||||
all: ${TARGET} ${DATA}
|
||||
@${TRUE}
|
||||
|
||||
prog: prog.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
# alternative executable
|
||||
#
|
||||
alt: ${ALT_TARGET}
|
||||
@${TRUE}
|
||||
|
||||
prog.orig: prog.orig.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
# data files
|
||||
#
|
||||
data: ${DATA}
|
||||
@${TRUE}
|
||||
|
||||
|
||||
###############
|
||||
# utility rules
|
||||
###############
|
||||
#
|
||||
everything: all alt
|
||||
|
||||
clean:
|
||||
${RM} -f ${OBJ} ${ALT_OBJ}
|
||||
|
||||
clobber: clean
|
||||
${RM} -f ${TARGET} ${ALT_TARGET}
|
||||
@-if [ -e sandwich ]; then \
|
||||
${RM} -f sandwich; \
|
||||
echo 'ate sandwich'; \
|
||||
fi
|
||||
|
||||
nuke: clobber
|
||||
@${TRUE}
|
||||
|
||||
dist_clean: nuke
|
||||
@${TRUE}
|
||||
|
||||
install:
|
||||
@echo "Surely you are performing, Dr. May!"
|
||||
@${TRUE}
|
||||
|
||||
# backwards compatibility
|
||||
#
|
||||
build: all
|
||||
@${TRUE}
|
||||
|
||||
|
||||
##################
|
||||
# 133t hacker rulz
|
||||
##################
|
||||
#
|
||||
love:
|
||||
@echo 'not war?'
|
||||
@${TRUE}
|
||||
|
||||
haste:
|
||||
$(MAKE) waste
|
||||
@${TRUE}
|
||||
|
||||
waste:
|
||||
@echo 'haste'
|
||||
@${TRUE}
|
||||
|
||||
make:
|
||||
@echo 'Attend a maker faire'
|
||||
@${TRUE}
|
||||
|
||||
easter_egg:
|
||||
@echo you expected to often mis-understand this $${RANDOM} magic
|
||||
@echo chongo '<was here>' "/\\oo/\\"
|
||||
@echo Eggy
|
||||
|
||||
fabricate fashion form frame manufacture produce: make
|
||||
@${TRUE}
|
||||
|
||||
sandwich:
|
||||
@if [ `id -u` -eq 0 ]; then \
|
||||
echo 'Okay.'; \
|
||||
echo $${RANDOM}`date +%s`$${RANDOM} > $@; \
|
||||
else \
|
||||
echo 'What? Make it yourself.'; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
# Understand the history of the Homebrew Computer Club
|
||||
# as well as the West Coast Computer Faire and
|
||||
# you might be confused different. :-)
|
||||
#
|
||||
supernova: nuke
|
||||
@-if [ -r .code_anal ]; then \
|
||||
${RM} -f .code_anal_v6; \
|
||||
else \
|
||||
echo "planet deniers, like some members of the IAU, are so cute when they try to defend their logic"; \
|
||||
fi
|
||||
@echo A $@ helps ${MAKE} the elements that help form planets
|
||||
@${TRUE}
|
||||
|
||||
deep_magic:
|
||||
@-if [ -r .code_anal ]; then \
|
||||
ccode_analysis --deep_magic 3a3fabb90892eeb2f610ae0f74a35a970060665a063ab702bd686c17c4ae07f6 --FNV1a_hash_256_bit "prog"; \
|
||||
else \
|
||||
echo "Wrong! Do it again!"; \
|
||||
sleep 2; \
|
||||
echo "Wrong! Do it again!"; \
|
||||
sleep 2; \
|
||||
echo "Wrong! Do it again!"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
|
||||
magic: deep_magic
|
||||
@-if [ -r .code_anal ]; then \
|
||||
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_256_bit "prog"; \
|
||||
else \
|
||||
echo "If you don't eat yer meat, you can't have any pudding!"; \
|
||||
echo "How can you have any pudding if you don't eat yer meat?!"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
|
||||
# The IOCCC resident astronomer states
|
||||
#
|
||||
charon: supernova
|
||||
@echo $@ is a dwarf planet
|
||||
@echo dwarf is a type of planet
|
||||
@echo $@ is a planet
|
||||
|
||||
pluto: supernova
|
||||
${MAKE} charon
|
||||
@echo $@ is a dwarf planet
|
||||
@echo dwarf is a type of planet
|
||||
@echo $@ is a planet
|
||||
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
|
||||
Binary file not shown.
@@ -0,0 +1,113 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
|
||||
<link rel="stylesheet"
|
||||
type="text/css"
|
||||
href="../hint.css">
|
||||
<title>Most inflationary</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Most inflationary</h1>
|
||||
|
||||
<p>Fabrice Bellard<br>
|
||||
<a href="https://bellard.org/">https://bellard.org/</a></p>
|
||||
|
||||
<h2>Judges' comments:</h2>
|
||||
|
||||
<h3>To use:</h3>
|
||||
|
||||
<pre><code>make
|
||||
./prog > lena.ppm
|
||||
</code></pre>
|
||||
|
||||
<h3>Try:</h3>
|
||||
|
||||
<pre><code>eog lena.ppm # On Linux
|
||||
preview lena.ppm # On MacOS
|
||||
|
||||
wget http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png
|
||||
pngtopnm < Lenna.png | pnmscale 0.25 | cjpeg -arithmetic -dct float -quality 14 > small.jpg
|
||||
</code></pre>
|
||||
|
||||
<p>The file <code>small.jpg</code> will be approximately of the same size as the raw image data
|
||||
in the program. Compare the level of the detail and the artifacts of
|
||||
<code>small.jpg</code> and <code>lena.ppm</code>.</p>
|
||||
|
||||
<h3>Selected Judges Remarks:</h3>
|
||||
|
||||
<p>Compressing images is just a matter of simple arithmetic and some magic, isn’t it?</p>
|
||||
|
||||
<p>We could understand some of the arithmetic but none of the magic.</p>
|
||||
|
||||
<p>Deciphering the mechanism used for data encoding to make use
|
||||
of the whitespaces, braces and semicolons should be a slightly easier task.</p>
|
||||
|
||||
<h2>Author’s comments:</h2>
|
||||
|
||||
<p>This program outputs a 128x128 RGB image file to the standard output
|
||||
using the portable pixmap file format (PPM). It contains the famous
|
||||
“Lena” image which is used in many image compression tests.</p>
|
||||
|
||||
<p>The uncompressed image is 12 times larger than the source code of the
|
||||
program which includes the image data and the complete decoder. The
|
||||
actual image data is 1220 byte long, which gives a compression ratio
|
||||
of 40. Using a JPEG-like algorithm would not be enough to reach this
|
||||
level of compression (the Lena image would be barely recognizable). So
|
||||
the algorithm is based on the latest advances in image compression. It
|
||||
includes the following features:</p>
|
||||
|
||||
<ul>
|
||||
<li>DCT transform with variable block size (4x4, 8x8, 16x16 and 32x32)</li>
|
||||
<li>DC and directional predictors</li>
|
||||
<li>arithmetic coding</li>
|
||||
<li>YCgCo color space.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>The image data is encoded to a C string with some tricks to make the
|
||||
best use of the IOCCC size constraints. The identifiers were shortened
|
||||
to a single letter to save space. No specific obfuscation was needed
|
||||
as the algorithms already have a significant complexity.</p>
|
||||
|
||||
<p>Although the program was optimized to decompress its built-in image,
|
||||
it accepts to decompress image files from its standard
|
||||
input. Examples:</p>
|
||||
|
||||
<pre><code>./prog d < lena512.bin > lena512.ppm
|
||||
./prog d < fruits.bin > fruits.ppm
|
||||
./prog d < vintage_cars.bin > vintage_cars.ppm
|
||||
</code></pre>
|
||||
|
||||
<p>The original images for <a href="https://commons.wikimedia.org/wiki/File%3AFruits_oranges%2C_jardin_japonais_2.JPG">fruits</a> and <a href="https://commons.wikimedia.org/wiki/File%3ARed_Bull_Jungfrau_Stafette%2C_10th_stage_-_vintage_cars_%282%29.jpg">vintage cars</a> come from
|
||||
Wikipedia and were resized to a width of 1024 pixels. Warning: the
|
||||
program is not protected against invalid input.</p>
|
||||
|
||||
<p>The program should be portable on any Unix system. On Windows the line
|
||||
“<em>setmode(0, 32768); </em>setmode(1, 32768);” must be added at the start of
|
||||
the main() function to avoid unwanted carriage return characters in
|
||||
the output.</p>
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<!--
|
||||
(c) Copyright 1984-2018, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
|
||||
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
|
||||
|
||||
[judges]: http://www.ioccc.org/judges.html
|
||||
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
-->
|
||||
|
||||
<TABLE><TR>
|
||||
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
|
||||
<TD><P>© Copyright 1984-2018,
|
||||
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
|
||||
- All rights reserved<BR>
|
||||
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
|
||||
<TD> <!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
|
||||
</TR></TABLE>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,87 @@
|
||||
# Most inflationary
|
||||
|
||||
Fabrice Bellard
|
||||
<https://bellard.org/>
|
||||
|
||||
|
||||
## Judges' comments:
|
||||
### To use:
|
||||
|
||||
make
|
||||
./prog > lena.ppm
|
||||
|
||||
### Try:
|
||||
|
||||
eog lena.ppm # On Linux
|
||||
preview lena.ppm # On MacOS
|
||||
|
||||
wget http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png
|
||||
pngtopnm < Lenna.png | pnmscale 0.25 | cjpeg -arithmetic -dct float -quality 14 > small.jpg
|
||||
|
||||
The file `small.jpg` will be approximately of the same size as the raw image data
|
||||
in the program. Compare the level of the detail and the artifacts of
|
||||
`small.jpg` and `lena.ppm`.
|
||||
|
||||
### Selected Judges Remarks:
|
||||
|
||||
Compressing images is just a matter of simple arithmetic and some magic, isn't it?
|
||||
|
||||
We could understand some of the arithmetic but none of the magic.
|
||||
|
||||
Deciphering the mechanism used for data encoding to make use
|
||||
of the whitespaces, braces and semicolons should be a slightly easier task.
|
||||
|
||||
|
||||
## Author's comments:
|
||||
This program outputs a 128x128 RGB image file to the standard output
|
||||
using the portable pixmap file format (PPM). It contains the famous
|
||||
"Lena" image which is used in many image compression tests.
|
||||
|
||||
The uncompressed image is 12 times larger than the source code of the
|
||||
program which includes the image data and the complete decoder. The
|
||||
actual image data is 1220 byte long, which gives a compression ratio
|
||||
of 40. Using a JPEG-like algorithm would not be enough to reach this
|
||||
level of compression (the Lena image would be barely recognizable). So
|
||||
the algorithm is based on the latest advances in image compression. It
|
||||
includes the following features:
|
||||
|
||||
- DCT transform with variable block size (4x4, 8x8, 16x16 and 32x32)
|
||||
- DC and directional predictors
|
||||
- arithmetic coding
|
||||
- YCgCo color space.
|
||||
|
||||
The image data is encoded to a C string with some tricks to make the
|
||||
best use of the IOCCC size constraints. The identifiers were shortened
|
||||
to a single letter to save space. No specific obfuscation was needed
|
||||
as the algorithms already have a significant complexity.
|
||||
|
||||
Although the program was optimized to decompress its built-in image,
|
||||
it accepts to decompress image files from its standard
|
||||
input. Examples:
|
||||
|
||||
./prog d < lena512.bin > lena512.ppm
|
||||
./prog d < fruits.bin > fruits.ppm
|
||||
./prog d < vintage_cars.bin > vintage_cars.ppm
|
||||
|
||||
The original images for [fruits][1] and [vintage cars][2] come from
|
||||
Wikipedia and were resized to a width of 1024 pixels. Warning: the
|
||||
program is not protected against invalid input.
|
||||
|
||||
The program should be portable on any Unix system. On Windows the line
|
||||
"_setmode(0, 32768); _setmode(1, 32768);" must be added at the start of
|
||||
the main() function to avoid unwanted carriage return characters in
|
||||
the output.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
[1]: https://commons.wikimedia.org/wiki/File%3AFruits_oranges%2C_jardin_japonais_2.JPG
|
||||
[2]: https://commons.wikimedia.org/wiki/File%3ARed_Bull_Jungfrau_Stafette%2C_10th_stage_-_vintage_cars_%282%29.jpg
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
<!--
|
||||
(c) Copyright 1984-2018, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
|
||||
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
|
||||
|
||||
[judges]: http://www.ioccc.org/judges.html
|
||||
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
-->
|
||||
Binary file not shown.
@@ -0,0 +1,134 @@
|
||||
#include <math.h>
|
||||
#define e(a, d) for(a=0;a<d;a++)
|
||||
char*x=" {k/; y{ q ; } c { @; ={ S} c} W;; {4} k |; w{ +9;{; 8; 9{ S; /} y{ K} {;} l{ { ~{ ; V}k}g< t{ E v;M{ B}y} <{7;/; Y} t}kp; Y} $Ha{e} w};} R} /{>}a ;} ; ` $W-} D}B; e;f;*; ~;A;s O{ o;>{1; m{ `} R}]{ T} v}={ I} ; }a?&; A}$;W;R{u} `; j}W;s{e} A;[ R; X P; 4 ,F;({<8{#;%}@J{)} }o^*{u/{'}]{ *} } ;{ r} f /;}e} }w{ ${{;,; @ d $}];>(} I{ d} &; U} { y;Y} { P{ R} T}_{ }R } l { T}"
|
||||
"'; |; ${=} H} (}}8{cp{ s} #}+} 3}kF}<H .{ }G}x; r D c{; W; { b;6; k{}B;*}; ]} ~ { ;;} !}} x}v}n;^; 6V}Y{ h; ~ %*}! H; G{ r{ f;Y{ i}z} N %}.{; ( v} _} h; 7;<} ^;Z;0; ; <;<; M; N{ } _{O} !{f{]{M{;A{} 0;S}${ @;x}y}@ L;1 t{ 3{c{s{_{ `{ D{ ]}!; ${ _J;v+ } 3{B; ]{ } E6 .x{?+; {x; }v{$};6}T; O; ; (}X7} j; @} :}# c{ !{ }x KXt} >; ?{ c; ; W; ; l;} h}p} i{ % }P} /{ *} %L; ; !{ S{ n} "
|
||||
"x; { 1 J;v{ U}({ @ X{ k} H;4;e J 6;;v; G{{] &{A d{ lM{;K;; 4-{}} p h{; { rW; v{; f} }1{^&{9{{ ;~;n;q{ 9 R 6{ { u;a; ; U; ;Y} +}}2sk; 8 { JK;'i; ;$; W{ P!{{{P } [; (;Q; Un;+}g{C;{{ ; <{ vS} b;6`} ?{+ %; }n;q{ r}k; ;{c{ S} 2}~{ 4;RW v} R; kI}|; d; [ O}5; ;;}Z d { {&;h o{ V v ; _{{/} F{f{r{4{{?{ 4;S} :;];E} ; &} #e !{>{H; {O{ 0;} H; p; w}>{1}{ -} 4;"
|
||||
"S}} u L{ y} %;2 |{(} /;,{ )}Y;g} G}v;T} };}i {{};[{ E{q} g;T{ ={}R; k{ j;_;h}gPc;({ F;6} }} 3 ,}<; 0 P;{'t}u}; }U}s{8{ E} >{}E {G{H :{ Yog} }F D{ R{ -;M?;= q}_ U { ; I { |{{} 1{,}{ x{{ U{ s;J}} 6{>7;,{ D{ {{ ;]} ;M; &}{ V} n{& T~;({ }[; r{# u{X 9;L; Uf})} {T} p{ N; >{ > }}D} m{1{ {}X; o} w}$} ^v} K f ,} ^3; { @{_} _{ o; 4} h}H;#.{ {} ; <{ {G{ $;{ "
|
||||
"z {a{{D; ?|}{{ ; `} } Q}j;4} 3{Q} { * ;}r{a} } R{p @; N{ {f; A;8}L $}{ }}J{ } k{r} { [; -;p{ I{ { &}J; T} ?{Z{>; 5>; ]; wz ^} u;); H} ; L &; V E{1{g;C} V} ~;U; ^{ J; { /} {;(}y} aK /} .};K;N{w{ `{ }T{l`; #;N{lX; ?; +}{ w{ ; q; z;_;y} 8} &{X} V{ WG} ,; [}U{ v{ Q; w{ [ Y}N Yu i{ {!A{}{ b0; X~} ;-; 8{ E } ;F{ y{}{ ";
|
||||
int y[3][1<<20],i[2048],X[166],p,r=1,f,s,O,P;
|
||||
Q(){
|
||||
int b;
|
||||
r*=s;
|
||||
p*=s;
|
||||
if(s>>9){
|
||||
if(b=*x){
|
||||
p+=b-1-(b>10)-(b>13)-(b>34)-(b>92)<<4;
|
||||
b=x[1];
|
||||
x+=2;
|
||||
p+=b<33?(b^8)*2%5:(b^6)%3*4+(*x++^8)*2%5+4;
|
||||
}
|
||||
}
|
||||
else{
|
||||
b=getchar();
|
||||
p+=b<0?0:b;
|
||||
}
|
||||
}
|
||||
t(E){
|
||||
int u,k,F,*m;
|
||||
if(r<s)Q();
|
||||
m=X+E*2;
|
||||
F=*m+m[1]+2;
|
||||
u=r*(*m+1)/F;
|
||||
if(k=p>=u){
|
||||
p-=u;
|
||||
r-=u;
|
||||
}
|
||||
else r=u;
|
||||
m[k]++;
|
||||
if(F>63){
|
||||
*m/=2;
|
||||
m[1]/=2;
|
||||
}
|
||||
return k;
|
||||
}
|
||||
n(E){
|
||||
int a,b;
|
||||
a=0;
|
||||
while(!t(E+a))a++;
|
||||
b=1;
|
||||
while(a--)b=b<<1|t(4);
|
||||
return b-1;
|
||||
}
|
||||
R(S,Y,T,Z,U,d,V)int*S,*T;
|
||||
{
|
||||
int G,a,j,H;
|
||||
e(H,d)e(a,d){
|
||||
G=0;
|
||||
e(j,d)G+=T[j*Z+H*U]*lrint(cos(acos(-1)/d*(a+0.5)*j)*sqrt(2-!j)*1024);
|
||||
S[a*Y+H*U]=G+(1<<V-1)>>V;
|
||||
}
|
||||
}
|
||||
W(z,l,g){
|
||||
int v,a,j,I,d,k,A,*o,c,B,q,C,h,w,J;
|
||||
if(g>5||g>2&&t(g-3)){
|
||||
c=1<<--g;
|
||||
e(a,4)W(z+a%2*c,l+a/2*c,g);
|
||||
}
|
||||
else{
|
||||
c=1<<g;
|
||||
d=c*c;
|
||||
q=n(73);
|
||||
e(A,3){
|
||||
o=y[A]+l*f+z;
|
||||
B=A>0;
|
||||
e(a,d)i[a]=0;
|
||||
e(a,d){
|
||||
if(t(61+g*2+B))break;
|
||||
a+=n(5+B*10);
|
||||
k=1-2*t(3);
|
||||
i[a]=k*(n(25+(B+(a<d/8)*2)*10)+1)*(A?P:O);
|
||||
}
|
||||
if(!q){
|
||||
v=0;
|
||||
e(a,c){
|
||||
v+=l?o[-f+a]:0;
|
||||
v+=z?o[a*f-1]:0;
|
||||
}
|
||||
*i+=z&&l?v/2:v;
|
||||
}
|
||||
R(i+d,1,i,1,c,c,10);
|
||||
R(o,f,i+d,c,1,c,10+g);
|
||||
if(q){
|
||||
C=q<17;
|
||||
w=C?9-q:q-25;
|
||||
e(a,c)e(j,c){
|
||||
e(I,2){
|
||||
h=a*w+w;
|
||||
J=h&7;
|
||||
h=(h>>3)+j+I;
|
||||
if(k=h<0)h=(h*8+w/2)/w-2;
|
||||
h=h<c?h:c-1;
|
||||
i[I]=k^C?o[h*f-1]:o[-f+h];
|
||||
}
|
||||
o[C?j*f+a:a*f+j]+=*i*(8-J)+i[1]*J+4>>3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
K(b){
|
||||
putchar(b<0?0:b>255?255:b);
|
||||
}
|
||||
main(D){
|
||||
int a,l,L,M,g,N;
|
||||
s=D>1?256:1968;
|
||||
Q();
|
||||
g=n(5);
|
||||
f=1<<g;
|
||||
N=f-n(5);
|
||||
O=n(5);
|
||||
P=n(5);
|
||||
W(0,0,g);
|
||||
printf("P6 %d %d 255 ",f,N);
|
||||
e(a,N*f){
|
||||
l=y[0][a];
|
||||
L=y[1][a];
|
||||
M=y[2][a];
|
||||
D=l-L;
|
||||
K(D+M);
|
||||
K(l+L);
|
||||
K(D-M);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
#include <math.h>
|
||||
#define e(a, d) for(a=0;a<d;a++)
|
||||
char*v="T{ ; ; :}>{ y} 4}; 1} s; {;9{ - $} ; q{; } u;d} } 3{d} ,{ 3; 1fB{A{ }{+ D}9} v{p{ pa} { N{${ ;P;{ z; ({ .{*}n{w{ v; j{$}<}S}y}@; { Q`{UN 9}0@{Z}'{ {%; h; 5} g} e S ~ q}'{#;e; B{;M} mP; b{y 7{ u;rOK}%} b}3 { k _{ { a{D{ W} L} q { '}A; AX;u}76*- h{O;p} } q}s}M} Q;; Y }D; H{ A ASRs}* n}P-{ {F}u; G; l{ D} ~; ,; } }8}{+Z O c; ;M{ A{Q} g} }} n U;k; |{ {<; /} H B}},} } L;"
|
||||
"_{ j}1{ z} = h{ S;1; 2;O; ; h{P; v; c{ H;;N;d;l}P} a; DBx}3{5 e A; {u} { FZ}8} ; ; 7;;{ $}~{ ~{q [ x;n#}; #{W{3; M ;; =;5; ;{} s}; *; v^} QB}n 9}} 1e <;}g{v} C{ :{a{ } o} R} .}}} , { 4 VX{s}r@{v 3} 7{{; y;{ {K; v 2O; t}&} ; L} t}3/; );e{(]f; ,}(}Nx;7}X} {A;R{;<;[; G;C} O; o}W}{ s; ); }{}[} (} C} ; Y{ 0}8} {m}{K}{ ^{. ;}';^;O }M{z; J,;{ };; "
|
||||
"W; n H; f; {-; v{}; { !} F- r l} {m } ;P} 9{p{ C}}G ={ 3 @{ 5}4{ | ; q ^;f} + -{-; } w{ ]{Q;.{ r{ Z { C 4{ +}o; y} b{[; Wg{N} o{ 9;;,{ P{z;+}>; a{}}p[{{{{b{b; @H{{s; {=}&}0; }} 8{N} {X; }I; 3} W{ 9;P{ {} } Hi}A { U{}D;};t;s; S;+; {O}nV} 7; x{f{ P} 4}B{ M ;Y} g};?{ ;{ t;5K ;* { H}w; SE n{D} I{&; {} =9 }B; W{4}p; l{Au; q{X~ +;O{ $j {G; ;'rb}3 j9} }`} m}4; r; 8; y;r}"
|
||||
"t}>; ~} E; G} 9} 5 ;/i}p{:; C{I} ; 2{ c{ x}}} ?}5{ i{ <} {})} C{ V} ?;X*;P{L{ c{M;T{<_{ {}M; V; q{ } $}l}P{Y{ #{N{9);]} u{ {F ;( ' )%J } x =; Y Q{Q}I'}B { } g}|{! n ({} C; # |; {=}D{3} }L{F}#} ` k} M; ]} J{ }7} 4} Z} ]}} v6 ; X; Y{Qx}{ ;};{ .<{b}7{ } 6 ; {x; & {]{~; [ P r}X} W 9 } {O{ ;f ;)}:;&{-; Eg{)}{0} Z{S}y; } N;; ; k}Y{`z;}? Kv} &; 6 1; ^ Y{ }{){A{${ #} M w; "
|
||||
"6{ >}B}o}; M{ ({ ({}H; ` h j{z; }; 7;f; { L; #{;{#} 4} N{z j}{ o;3{j;l B} 9} F} J;F 2 ;FTw+} y{ _ };l{ }} 4} 8} ]} l{ }K; ;@}{ v;b0; 0; }V; *} R; p;j; &;_;9; ; {J;W #} { h;^{t;|Q} [;U; >} ^} / ~{ @} {n k{ N} {H{ j} {W; X; 8{ 3; u:}T{P;0; k; Z} v{X} {;{`{#{ ;n} ;U} d}d{&{n {|t{ aT} v} $}7;Q; f; W; O} E;} c} F{ 8}AA; ~{ `; w; x<;G}f}7;rE{ ~{ n}F 5} ^{ c{; {!{|} "
|
||||
"1{[} ;3} ;{ 8 a}pIg;9{ n} -} T} e{ !} ; /0{9;V{>; W}F; +}L} F{S} +{ , } o; { x; i; 9 ";
|
||||
int w[3][16384],h[512],T[160],p,q=1,g=128;
|
||||
M(){
|
||||
int b;
|
||||
q*=1968;
|
||||
p*=1968;
|
||||
if(b=*v){
|
||||
p+=b-1-(b>10)-(b>13)-(b>34)-(b>92)<<4;
|
||||
b=v[1];
|
||||
v+=2;
|
||||
p+=b<33?(b^8)*2%5:(b^6)%3*4+(*v++^8)*2%5+4;
|
||||
}
|
||||
}
|
||||
r(A){
|
||||
int s,j,B,*m;
|
||||
if(q<1968)M();
|
||||
m=T+A*2;
|
||||
B=*m+m[1]+2;
|
||||
s=q*(*m+1)/B;
|
||||
if(j=p>=s){
|
||||
p-=s;
|
||||
q-=s;
|
||||
}
|
||||
else q=s;
|
||||
m[j]++;
|
||||
if(B>63){
|
||||
*m/=2;
|
||||
m[1]/=2;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
C(A){
|
||||
int a,b;
|
||||
a=0;
|
||||
while(!r(A+a))a++;
|
||||
b=1;
|
||||
while(a--)b=b<<1|r(3);
|
||||
return b-1;
|
||||
}
|
||||
N(O,U,P,V,Q,d,R)int*O,*P;
|
||||
{
|
||||
int D,a,i,E;
|
||||
e(E,d)e(a,d){
|
||||
D=0;
|
||||
e(i,d)D+=P[i*V+E*Q]*(i>0?lrint(cos(acos(-1)/d*(a+0.5)*i)*1448.155):1024);
|
||||
O[a*U+E*Q]=D+(1<<R-1)>>R;
|
||||
}
|
||||
}
|
||||
S(x,k,l){
|
||||
int t,a,i,F,d,j,y,*n,c,z,o,G,f,u,H;
|
||||
if(l>2&&(l>4||r(0+l-3))){
|
||||
c=1<<--l;
|
||||
e(a,4)S(x+a%2*c,k+a/2*c,l);
|
||||
}
|
||||
else{
|
||||
c=1<<l;
|
||||
d=c*c;
|
||||
o=C(70);
|
||||
e(y,3){
|
||||
n=w[y]+k*g+x;
|
||||
z=y>0;
|
||||
e(a,d)h[a]=0;
|
||||
e(a,d){
|
||||
if(r(60+l*2+z))break;
|
||||
a+=C(4+z*10);
|
||||
j=1-2*r(2);
|
||||
h[a]=j*(C(24+(z+(a<d/8)*2)*10)+1)*(y?76:38);
|
||||
}
|
||||
if(!o){
|
||||
t=0;
|
||||
e(a,c){
|
||||
t+=k?n[-g+a]:0;
|
||||
t+=x?n[a*g-1]:0;
|
||||
}
|
||||
*h+=x&&k?t/2:t;
|
||||
}
|
||||
N(h+d,1,h,1,c,c,10);
|
||||
N(n,g,h+d,c,1,c,10+l);
|
||||
if(o){
|
||||
u=(G=o<17)?9-o:o-25;
|
||||
e(a,c)e(i,c){
|
||||
e(F,2){
|
||||
f=a*u+u;
|
||||
H=f&7;
|
||||
f=(f>>3)+i+F;
|
||||
if(j=f<0)f=(f*8+u/2)/u-2;
|
||||
f=f<c?f:c-1;
|
||||
h[F]=j^G?n[f*g-1]:n[-g+f];
|
||||
}
|
||||
n[G?i*g+a:a*g+i]+=(*h*(8-H)+h[1]*H+4)>>3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
I(b){
|
||||
putchar(b<0?0:b>255?255:b);
|
||||
}
|
||||
main(){
|
||||
int a,k,J,K,L;
|
||||
M();
|
||||
S(0,0,7);
|
||||
puts("P6\n128 128\n255");
|
||||
e(a,g*g){
|
||||
k=w[0][a];
|
||||
J=w[1][a];
|
||||
K=w[2][a];
|
||||
L=k-J;
|
||||
I(L+K);
|
||||
I(k+J);
|
||||
I(L-K);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,286 @@
|
||||
#!/usr/bin/env make
|
||||
#
|
||||
# 2018 makefile
|
||||
#
|
||||
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
|
||||
# is licensed under:
|
||||
#
|
||||
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
|
||||
#
|
||||
# See: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
|
||||
################
|
||||
# tool locations
|
||||
################
|
||||
#
|
||||
SHELL= /bin/bash
|
||||
CP= cp
|
||||
CPP= cpp
|
||||
GUNZIP= gunzip
|
||||
BUNZIP2= bunzip2
|
||||
GZIP_PROG= gzip
|
||||
BZIP2= bzip2
|
||||
CURL= curl
|
||||
DD= dd
|
||||
LD= ld
|
||||
MAKE= make
|
||||
RM= rm
|
||||
SED= sed
|
||||
TAR= tar
|
||||
TRUE= true
|
||||
MKDIR= mkdir
|
||||
MV= mv
|
||||
TR= tr
|
||||
GREP= grep
|
||||
SORT= sort
|
||||
UNIQ= uniq
|
||||
|
||||
# Set X11_LIBDIR to the directory where the X11 library resides
|
||||
#
|
||||
#X11_LIBDIR= /usr/X11R6/lib
|
||||
#X11_LIBDIR= /usr/X11/lib
|
||||
X11_LIBDIR= /opt/X11/lib
|
||||
|
||||
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
|
||||
#
|
||||
#X11_INCDIR= /usr/X11R6/include
|
||||
#X11_INCDIR= /usr/X11/include
|
||||
X11_INCDIR= /opt/X11/include
|
||||
|
||||
# Compiler warnings
|
||||
#
|
||||
#CWARN=
|
||||
#CWARN= -Wall
|
||||
#CWARN= -Wall -Wextra
|
||||
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
|
||||
#CWARN= -Wall -Wextra -Weverything
|
||||
#CWARN= -Wall -Wextra -Weverything -pedantic
|
||||
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
|
||||
|
||||
# Silence warnings that ${CWARN} would normally complain about
|
||||
#
|
||||
CSILENCE=
|
||||
#CSILENCE= -Wno-implicit-int
|
||||
|
||||
# compiler standard
|
||||
#
|
||||
#CSTD=
|
||||
#CSTD= -ansi
|
||||
CSTD= -std=c11
|
||||
|
||||
# compiler bit architecture
|
||||
#
|
||||
# Some entries require 32-bitness:
|
||||
# ARCH= -m32
|
||||
#
|
||||
# Some entries require 64-bitness:
|
||||
# ARCH= -m64
|
||||
#
|
||||
# By default we assume nothing:
|
||||
#
|
||||
ARCH=
|
||||
|
||||
# defines that are needed to compile
|
||||
#
|
||||
CDEFINE=
|
||||
#CDEFINE= -DIOCCC=25
|
||||
|
||||
# include files that are needed to compile
|
||||
#
|
||||
#CINCLUDE=
|
||||
#CINCLUDE= -include stdlib.h
|
||||
CINCLUDE= -include stdio.h
|
||||
#CINCLUDE= -include stdlib.h -include stdio.h
|
||||
#CINCLUDE= -I ${X11_INCDIR}
|
||||
|
||||
# optimization
|
||||
#
|
||||
# Most compiles will safely use -O2. Some can use only -O1 or -O.
|
||||
# A few compilers have broken optimizers or this entry make break
|
||||
# under those buggy optimizers and thus you may not want anything.
|
||||
# Reasonable compilers will allow for -O3.
|
||||
#
|
||||
#OPT=
|
||||
#OPT= -O
|
||||
#OPT= -O1
|
||||
#OPT= -O2
|
||||
OPT= -O3
|
||||
|
||||
# default flags for ANSI C compilation
|
||||
#
|
||||
CFLAGS= ${CSTD} ${CWARN} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
|
||||
|
||||
# Libraries needed to build
|
||||
#
|
||||
LIBS=
|
||||
#LIBS= -L ${X11_LIBDIR}
|
||||
|
||||
# ANSI compiler
|
||||
#
|
||||
# Set CC to the name of your ANSI compiler.
|
||||
#
|
||||
# Some entries seem to need gcc. If you have gcc, set
|
||||
# both CC and MAY_NEED_GCC to gcc.
|
||||
#
|
||||
# If you do not have gcc, set CC to the name of your ANSI compiler, and
|
||||
# set MAY_NEED_GCC to either ${CC} (and hope for the best) or to just :
|
||||
# to disable such programs.
|
||||
#
|
||||
CC= cc
|
||||
#CC=clang
|
||||
MAY_NEED_GCC= gcc
|
||||
|
||||
|
||||
##############################
|
||||
# Special flags for this entry
|
||||
##############################
|
||||
#
|
||||
OBJ= prog.o
|
||||
DATA=
|
||||
TARGET= prog prog.nowarn
|
||||
#
|
||||
ALT_OBJ= prog.nowarn.o
|
||||
ALT_TARGET= prog.nowarn
|
||||
|
||||
|
||||
#################
|
||||
# build the entry
|
||||
#################
|
||||
#
|
||||
all: ${TARGET} ${DATA}
|
||||
@${TRUE}
|
||||
|
||||
prog: prog.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
# alternative executable
|
||||
#
|
||||
alt: ${ALT_TARGET}
|
||||
@${TRUE}
|
||||
|
||||
prog.nowarn: prog.nowarn.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
# data files
|
||||
#
|
||||
data: ${DATA}
|
||||
@${TRUE}
|
||||
|
||||
|
||||
###############
|
||||
# utility rules
|
||||
###############
|
||||
#
|
||||
everything: all alt
|
||||
|
||||
clean:
|
||||
${RM} -f ${OBJ} ${ALT_OBJ}
|
||||
|
||||
clobber: clean
|
||||
${RM} -f ${TARGET} ${ALT_TARGET}
|
||||
@-if [ -e sandwich ]; then \
|
||||
${RM} -f sandwich; \
|
||||
echo 'ate sandwich'; \
|
||||
fi
|
||||
|
||||
nuke: clobber
|
||||
@${TRUE}
|
||||
|
||||
dist_clean: nuke
|
||||
@${TRUE}
|
||||
|
||||
install:
|
||||
@echo "Surely you are performing, Dr. May!"
|
||||
@${TRUE}
|
||||
|
||||
# backwards compatibility
|
||||
#
|
||||
build: all
|
||||
@${TRUE}
|
||||
|
||||
|
||||
##################
|
||||
# 133t hacker rulz
|
||||
##################
|
||||
#
|
||||
love:
|
||||
@echo 'not war?'
|
||||
@${TRUE}
|
||||
|
||||
haste:
|
||||
$(MAKE) waste
|
||||
@${TRUE}
|
||||
|
||||
waste:
|
||||
@echo 'haste'
|
||||
@${TRUE}
|
||||
|
||||
make:
|
||||
@echo 'Attend a maker faire'
|
||||
@${TRUE}
|
||||
|
||||
easter_egg:
|
||||
@echo you expected to often mis-understand this $${RANDOM} magic
|
||||
@echo chongo '<was here>' "/\\oo/\\"
|
||||
@echo Eggy
|
||||
|
||||
fabricate fashion form frame manufacture produce: make
|
||||
@${TRUE}
|
||||
|
||||
sandwich:
|
||||
@if [ `id -u` -eq 0 ]; then \
|
||||
echo 'Okay.'; \
|
||||
echo $${RANDOM}`date +%s`$${RANDOM} > $@; \
|
||||
else \
|
||||
echo 'What? Make it yourself.'; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
# Understand the history of the Homebrew Computer Club
|
||||
# as well as the West Coast Computer Faire and
|
||||
# you might be confused different. :-)
|
||||
#
|
||||
supernova: nuke
|
||||
@-if [ -r .code_anal ]; then \
|
||||
${RM} -f .code_anal_v6; \
|
||||
else \
|
||||
echo "planet deniers, like some members of the IAU, are so cute when they try to defend their logic"; \
|
||||
fi
|
||||
@echo A $@ helps ${MAKE} the elements that help form planets
|
||||
@${TRUE}
|
||||
|
||||
deep_magic:
|
||||
@-if [ -r .code_anal ]; then \
|
||||
ccode_analysis --deep_magic 3a3fabb90892eeb2f610ae0f74a35a970060665a063ab702bd686c17c4ae07f6 --FNV1a_hash_256_bit "prog"; \
|
||||
else \
|
||||
echo "Wrong! Do it again!"; \
|
||||
sleep 2; \
|
||||
echo "Wrong! Do it again!"; \
|
||||
sleep 2; \
|
||||
echo "Wrong! Do it again!"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
|
||||
magic: deep_magic
|
||||
@-if [ -r .code_anal ]; then \
|
||||
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_256_bit "prog"; \
|
||||
else \
|
||||
echo "If you don't eat yer meat, you can't have any pudding!"; \
|
||||
echo "How can you have any pudding if you don't eat yer meat?!"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
|
||||
# The IOCCC resident astronomer states
|
||||
#
|
||||
charon: supernova
|
||||
@echo $@ is a dwarf planet
|
||||
@echo dwarf is a type of planet
|
||||
@echo $@ is a planet
|
||||
|
||||
pluto: supernova
|
||||
${MAKE} charon
|
||||
@echo $@ is a dwarf planet
|
||||
@echo dwarf is a type of planet
|
||||
@echo $@ is a planet
|
||||
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
|
||||
@@ -0,0 +1,254 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
|
||||
<link rel="stylesheet"
|
||||
type="text/css"
|
||||
href="../hint.css">
|
||||
<title>Best one-liner</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Best one-liner</h1>
|
||||
|
||||
<p>Dave Burton<br>
|
||||
<a href="http://ioccc.snox.net">http://ioccc.snox.net</a></p>
|
||||
|
||||
<h2>Judges' comments:</h2>
|
||||
|
||||
<h3>To use:</h3>
|
||||
|
||||
<pre><code>make
|
||||
./prog < any-file
|
||||
</code></pre>
|
||||
|
||||
<h3>Try:</h3>
|
||||
|
||||
<pre><code>./prog < prog
|
||||
./prog < prog.c
|
||||
</code></pre>
|
||||
|
||||
<h3>Selected Judges Remarks:</h3>
|
||||
|
||||
<p>One line, one array, one loop and one statement but it prints many bytes. It won.</p>
|
||||
|
||||
<h2>Author’s comments:</h2>
|
||||
|
||||
<p>Feed this anything on stdin.</p>
|
||||
|
||||
<p>The included script may be used as a driver program for this entry.
|
||||
It adds several nice-to-have features, and allows salt-to-taste customizability.</p>
|
||||
|
||||
<p>This code has been compiled and tested on:</p>
|
||||
|
||||
<ul>
|
||||
<li>OSX-10.11, gcc 4.2.1 and clang 3.0, -O0 and -O3</li>
|
||||
<li>X86-Linux, gcc 4.1.2 and 4.8.4, -O0 and -O3</li>
|
||||
<li>ARM-QEMU, gcc 4.8.4, -O0 and -O3</li>
|
||||
<li>X86-FreeBSD 10.3, clang 3.4.1, -O0 and -O3</li>
|
||||
<li>TCC 0.9.26 (x86-64) (used as a proxy for <a href="http://ioccc.org/years.html#2001_bellard">2001/bellard</a>)</li>
|
||||
<li>UNIX V7 pcc (Johnson’s C compiler) on a <a href="http://simh.trailing-edge.com/">simulated PDP-11/45</a>
|
||||
(see spoiler for further detail)</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<div style="margin-bottom:60em;margin-top:4em"><strong>Spoiler below; scroll down.</strong></div>
|
||||
|
||||
|
||||
<h2>SPOILER</h2>
|
||||
|
||||
<p>This started life as a personal challenge: write the shortest hex dump utility in C.</p>
|
||||
|
||||
<p>The self-imposed ground rules in the hunt for shortest:
|
||||
the code has to output correctly,
|
||||
no extraneous newlines, the code must be portable,
|
||||
and without bypassing the solution using execve(2),
|
||||
or functions built upon it (system(3), popen(3), etc). E.g:</p>
|
||||
|
||||
<pre><code>main(){system("hd");} // it's turtles all the way down!
|
||||
</code></pre>
|
||||
|
||||
<p>is not acceptable.
|
||||
And, “output correctly” is the output format of this entry. QED.</p>
|
||||
|
||||
<p>Early attempts ended up at a reasonably short 157 characters.
|
||||
This was too long for a one-liner, so it had to be formatted as something more interesting.
|
||||
This solution is pleasing, but a true one-liner was the hoped-for goal.
|
||||
Here is the 157 character version in it’s entirety:</p>
|
||||
|
||||
<pre><code>char O,o[ 20];L(O){
|
||||
putchar ( O+ 48+39 *(9<
|
||||
O));} I(O) {L(~ 15);
|
||||
O|| puts(o);} main (l){
|
||||
for(;~(l=getchar()) ;I(O
|
||||
&=15 ))o[ O++ ]=4<
|
||||
(4^l >>5) ?l: 46,L
|
||||
(l>> 4),L (l&15);O&&
|
||||
I(o[ O]=0 );}//157c
|
||||
</code></pre>
|
||||
|
||||
<p>While thinking about this in the shower (you are not the only one that does this!)
|
||||
came the idea which reduced the code to just 119 chars.
|
||||
This dramatic reduction started to feel close to minimal, and the hunt resumed.
|
||||
The progression to the present size is interesting,
|
||||
and it is interesting that the same algorithm can be expressed so differently
|
||||
by slight rearrangement of its parts.</p>
|
||||
|
||||
<pre><code>// 119
|
||||
char O,o[20];main(l){for(;~(l=getchar());O||puts(o))o[O++]=isprint(l)?l:46,O&=15,printf("%02x ",l);O[o]=0;O&&puts(o);}
|
||||
// 116
|
||||
char O,o[20];main(l){for(;O++[o]=~(l=getchar())?4<(4^l>>5)?l:46:0;(O&=15)||puts(o))printf("%02x ",l);O>1&&puts(o);}
|
||||
// 115
|
||||
char O,o[20];main(l){for(;O[o]=~(l=getchar())?4<(4^l>>5)?l:46:0;(O=-~O&15)||puts(o))printf("%02x ",l);O&&puts(o);}
|
||||
// 113
|
||||
char O,o[20];main(l){for(;~l;(O=~l?printf("%02x ",l),-~O&15:!O)||puts(o))O[o]=~(l=getchar())?4<(4^l>>5)?l:46:0;}
|
||||
// 112
|
||||
char O,o[20];main(l){for(;~l;(O=~l?-~O&printf("%02x ",l)*5:!O)||puts(o))O[o]=~(l=getchar())?4<(4^l>>5)?l:46:0;}
|
||||
// 111
|
||||
char O,o[20];main(l){for(;~l;O||puts(o))O=(O[o]=~(l=getchar())?4<(4^l>>5)?l:46:0)?-~O&printf("%02x ",l)*5:!O;}
|
||||
// 110
|
||||
char O,o[0];main(l){for(;~l;O||puts(o))O=(O[o]=~(l=getchar())?4<(4^l>>5)?l:46:0)?-~O&printf("%02x ",l)*5:!O;}
|
||||
// 109
|
||||
char O,o[];main(l){for(;~l;O||puts(o))O=(O[o]=~(l=getchar())?4<(4^l>>5)?l:46:0)?-~O&printf("%02x ",l)*5:!O;}
|
||||
</code></pre>
|
||||
|
||||
<p>There are solutions without the ASCII sidebar that are significantly shorter.
|
||||
These do not compete in the same category, since their output is materially different.
|
||||
They are derived from the solutions above, but are still fascinating as concise utilities,
|
||||
so here is their progression, for the curious:</p>
|
||||
|
||||
<pre><code>// 102
|
||||
I;O(O){putchar(O+48+39*(9<O));}main(l){for(;~(l=getchar());O(++I&15?~15:~37))O(l>>4),O(l&15);O(-38);}
|
||||
// 80
|
||||
O;main(l){while(~(l=getchar()))printf("%02x%c",l,++O&15?32:10);O&15&&puts("");}
|
||||
// 78
|
||||
O;main(l){for(;~l;(O=~(l=getchar())?printf("%02x ",l),-~O&15:!O)||puts(""));}
|
||||
// 77
|
||||
O;main(l){for(;~l;(O=~(l=getchar())?-~O&printf("%02x ",l)*5:!O)||puts(""));}
|
||||
// 76
|
||||
O;main(l){for(;~l;O||puts(&O))O=~(l=getchar())?-~O&printf("%02x ",l)*5:!O;}
|
||||
</code></pre>
|
||||
|
||||
<p>It is possible to reduce the size of each of these by one by eliding the trailing newline.
|
||||
This was not reported above since the newline kept getting appended by processing software,
|
||||
and it is more interesting to remove characters by changing code than by filtering:</p>
|
||||
|
||||
<pre><code>$ tr -d '\012' < 109.c | wc -c
|
||||
108
|
||||
$ tr -d '\012' < 76.c | wc -c
|
||||
75
|
||||
$ tr -d '\012' < 109.c | cc -o 108 -xc -
|
||||
$ verify 108
|
||||
$
|
||||
</code></pre>
|
||||
|
||||
<p>An obfuscated hex dump has been done before:
|
||||
<a href="http://ioccc.org/1986/bright/bright.c">1986/bright/bright.c</a> is similar in function,
|
||||
but it uses more characters in just setting up its obfuscation than this entire solution!</p>
|
||||
|
||||
<h2>BIGGER SPOILER</h2>
|
||||
|
||||
<p>If you are unhappy with the way DEL (character 127) is handled,
|
||||
replace the cryptic expression <code>4<(4^l>>5)?l:46</code> with <code>32>l|l>126?46:l</code>.
|
||||
Both take the same number of characters, but the former is a bit more interesting.
|
||||
Bonus question: how does the first expression work?</p>
|
||||
|
||||
<h2>BIGGEST SPOILER (and some history)</h2>
|
||||
|
||||
<p>Technically, <code>char o[0];</code> is illegal (SS 6.7.6.2) according to ISO (N1570).
|
||||
And <code>char o[];</code> is a conditionally supported feature (SS 6.7.6.2, 6.10.8.3).
|
||||
However, it works in modern C implementations as an extension,
|
||||
including GCC, Clang and TCC, for X86 and ARM,
|
||||
on multiple operating systems (Linux, OSX, FreeBSD), so it is <em>functionally</em> correct.
|
||||
MicroSoft Visual C++ does not allow <code>char o[]</code> or <code>char o[0]</code>,
|
||||
and implements its close relative <code>char o[1]</code>
|
||||
such that writing more than a single char will cause a fault, which is <em>technically</em> correct.</p>
|
||||
|
||||
<p>But how does this work at all, even as an extension?
|
||||
<code>o[]</code> allocates one(!) byte in a zero-filled data area (formerly BSS).
|
||||
The UNIX-derived systems this code was run upon all place the
|
||||
storage of <code>O</code> and <code>o</code> into a zero-filled VM page with nothing following:
|
||||
thus, there are plenty of available and unused zero bytes following <code>O</code>, addressed via <code>o</code>,
|
||||
and this code only needs 17.
|
||||
This is <em>undefined</em> behavior, but as shown, it is widely available.</p>
|
||||
|
||||
<p>The <a href="http://minnie.tuhs.org/cgi-bin/utree.pl">1979 Seventh Edition UNIX</a> (v7) system pre-dates the IOCCC by several years,
|
||||
and the source code to <code>sh</code>(1) was a <a href="http://ioccc.org/all/README">significant inspiration for this contest</a>.
|
||||
There are two C compilers present: <code>cc</code> written by Dennis Ritchie, and <code>pcc</code> written by Steven Johnson.
|
||||
The nested conditional expressions in 116 and smaller are too complex for <code>cc</code> (“Illegal conditional”)
|
||||
but <code>pcc</code> handles them correctly, and neither compiler accepts <code>char o[]</code> or <code>char o[0]</code> nor puts the bytes in
|
||||
a zero-filled page (as a paged VM was not yet written for UNIX).</p>
|
||||
|
||||
<p>More significant is that v7 <code>printf</code>(3) does not report the number of characters written,
|
||||
and therefore 111 compiles but does not work correctly;
|
||||
113 is the shortest code that compiles and runs correctly in Ancient UNIX.</p>
|
||||
|
||||
<blockquote><p>Interesting digression: v7 <code>printf</code> (<code>_doprnt</code>) was written in PDP-11 assembler.
|
||||
It pre-dates <code>varargs.h</code>, and assembly was the only way to gain access to the variable argument types.
|
||||
The first edition <em>The C Programming Language</em>, 1978, page 71, remarks:</p>
|
||||
|
||||
<blockquote><p>By the way, there is no entirely satisfactory way to write a portable function
|
||||
that accepts a variable number of arguments, because there is no portable way
|
||||
for the called function to determine how many arguments where actually passed to it in a given call.
|
||||
…
|
||||
<code>printf</code>, the most common C function with a variable number of arguments,
|
||||
… is also non-portable and must be modified for different environments.</p></blockquote>
|
||||
|
||||
<p>It is fascinating to explore the roots of C through the history of the operating system
|
||||
it was birthed within. C is often criticized as a difficult, inscrutable language,
|
||||
but as this contest demonstrates, this is in parody.
|
||||
<em>Shell-gol</em> is one of those instances where someone <a href="http://www.computerworld.com.au/article/279011/a-z_programming_languages_bourne_shell_sh/?pp=4">preferred a different language</a>,
|
||||
and (ab)used the preprocessor to re-mold C into something they found comfortable.
|
||||
Most of the rest of the system, especially in the kernel,
|
||||
are models of clarity and efficient expression.</p></blockquote>
|
||||
|
||||
<h2>TL;DR</h2>
|
||||
|
||||
<p>So which version is the shortest, portable hex dump?</p>
|
||||
|
||||
<ul>
|
||||
<li>109 works with (most?) modern Unix-like systems and compilers, see example list above.</li>
|
||||
<li>111 works adds Microsoft, is standards-approved, and does not exploit undefined behavior.</li>
|
||||
<li>113 works on Ancient UNIX and the portable C compiler.</li>
|
||||
<li>119 works on all platforms, including the original Ritchie PDP-11 C compiler.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Coda</h2>
|
||||
|
||||
<p>Clearly, the smallest possible program violates modern best practice.
|
||||
It is not even possible to compile cleanly, but it will compile correctly.</p>
|
||||
|
||||
<p>Included is <code>prog.nowarn.c</code>, a modern C implementation that is – perhaps – the smallest,
|
||||
clean-compiling version using <code>clang</code> or <code>gcc</code> with <code>-Wall -pedantic</code>.
|
||||
Note that while this is larger than all but the original attempt,
|
||||
it will <em>not</em> work with the original Ritchie PDP-11 C compiler,
|
||||
since the expression within the ternary remains too complex.</p>
|
||||
|
||||
<p>Try</p>
|
||||
|
||||
<pre><code>cat prog.c prog.nowarn.c
|
||||
</code></pre>
|
||||
|
||||
<p>to compare the differences (<code>diff</code> is not helpful on a one-liner).</p>
|
||||
|
||||
<hr />
|
||||
|
||||
<!--
|
||||
(c) Copyright 1984-2018, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
|
||||
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
|
||||
|
||||
[judges]: http://www.ioccc.org/judges.html
|
||||
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
-->
|
||||
|
||||
<TABLE><TR>
|
||||
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
|
||||
<TD><P>© Copyright 1984-2018,
|
||||
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
|
||||
- All rights reserved<BR>
|
||||
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
|
||||
<TD> <!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
|
||||
</TR></TABLE>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,224 @@
|
||||
# Best one-liner
|
||||
|
||||
Dave Burton
|
||||
<http://ioccc.snox.net>
|
||||
|
||||
|
||||
## Judges' comments:
|
||||
### To use:
|
||||
|
||||
make
|
||||
./prog < any-file
|
||||
|
||||
### Try:
|
||||
|
||||
./prog < prog
|
||||
./prog < prog.c
|
||||
|
||||
### Selected Judges Remarks:
|
||||
|
||||
One line, one array, one loop and one statement but it prints many bytes. It won.
|
||||
|
||||
## Author's comments:
|
||||
Feed this anything on stdin.
|
||||
|
||||
The included script may be used as a driver program for this entry.
|
||||
It adds several nice-to-have features, and allows salt-to-taste customizability.
|
||||
|
||||
This code has been compiled and tested on:
|
||||
|
||||
* OSX-10.11, gcc 4.2.1 and clang 3.0, -O0 and -O3
|
||||
* X86-Linux, gcc 4.1.2 and 4.8.4, -O0 and -O3
|
||||
* ARM-QEMU, gcc 4.8.4, -O0 and -O3
|
||||
* X86-FreeBSD 10.3, clang 3.4.1, -O0 and -O3
|
||||
* TCC 0.9.26 (x86-64) (used as a proxy for [2001/bellard](http://ioccc.org/years.html#2001_bellard))
|
||||
* UNIX V7 pcc (Johnson's C compiler) on a [simulated PDP-11/45](http://simh.trailing-edge.com/)
|
||||
(see spoiler for further detail)
|
||||
|
||||
<div style="margin-bottom:60em;margin-top:4em"><strong>Spoiler below; scroll down.</strong></div>
|
||||
|
||||
SPOILER
|
||||
-------
|
||||
|
||||
This started life as a personal challenge: write the shortest hex dump utility in C.
|
||||
|
||||
The self-imposed ground rules in the hunt for shortest:
|
||||
the code has to output correctly,
|
||||
no extraneous newlines, the code must be portable,
|
||||
and without bypassing the solution using execve(2),
|
||||
or functions built upon it (system(3), popen(3), etc). E.g:
|
||||
|
||||
main(){system("hd");} // it's turtles all the way down!
|
||||
|
||||
is not acceptable.
|
||||
And, "output correctly" is the output format of this entry. QED.
|
||||
|
||||
Early attempts ended up at a reasonably short 157 characters.
|
||||
This was too long for a one-liner, so it had to be formatted as something more interesting.
|
||||
This solution is pleasing, but a true one-liner was the hoped-for goal.
|
||||
Here is the 157 character version in it's entirety:
|
||||
|
||||
char O,o[ 20];L(O){
|
||||
putchar ( O+ 48+39 *(9<
|
||||
O));} I(O) {L(~ 15);
|
||||
O|| puts(o);} main (l){
|
||||
for(;~(l=getchar()) ;I(O
|
||||
&=15 ))o[ O++ ]=4<
|
||||
(4^l >>5) ?l: 46,L
|
||||
(l>> 4),L (l&15);O&&
|
||||
I(o[ O]=0 );}//157c
|
||||
|
||||
While thinking about this in the shower (you are not the only one that does this!)
|
||||
came the idea which reduced the code to just 119 chars.
|
||||
This dramatic reduction started to feel close to minimal, and the hunt resumed.
|
||||
The progression to the present size is interesting,
|
||||
and it is interesting that the same algorithm can be expressed so differently
|
||||
by slight rearrangement of its parts.
|
||||
|
||||
// 119
|
||||
char O,o[20];main(l){for(;~(l=getchar());O||puts(o))o[O++]=isprint(l)?l:46,O&=15,printf("%02x ",l);O[o]=0;O&&puts(o);}
|
||||
// 116
|
||||
char O,o[20];main(l){for(;O++[o]=~(l=getchar())?4<(4^l>>5)?l:46:0;(O&=15)||puts(o))printf("%02x ",l);O>1&&puts(o);}
|
||||
// 115
|
||||
char O,o[20];main(l){for(;O[o]=~(l=getchar())?4<(4^l>>5)?l:46:0;(O=-~O&15)||puts(o))printf("%02x ",l);O&&puts(o);}
|
||||
// 113
|
||||
char O,o[20];main(l){for(;~l;(O=~l?printf("%02x ",l),-~O&15:!O)||puts(o))O[o]=~(l=getchar())?4<(4^l>>5)?l:46:0;}
|
||||
// 112
|
||||
char O,o[20];main(l){for(;~l;(O=~l?-~O&printf("%02x ",l)*5:!O)||puts(o))O[o]=~(l=getchar())?4<(4^l>>5)?l:46:0;}
|
||||
// 111
|
||||
char O,o[20];main(l){for(;~l;O||puts(o))O=(O[o]=~(l=getchar())?4<(4^l>>5)?l:46:0)?-~O&printf("%02x ",l)*5:!O;}
|
||||
// 110
|
||||
char O,o[0];main(l){for(;~l;O||puts(o))O=(O[o]=~(l=getchar())?4<(4^l>>5)?l:46:0)?-~O&printf("%02x ",l)*5:!O;}
|
||||
// 109
|
||||
char O,o[];main(l){for(;~l;O||puts(o))O=(O[o]=~(l=getchar())?4<(4^l>>5)?l:46:0)?-~O&printf("%02x ",l)*5:!O;}
|
||||
|
||||
There are solutions without the ASCII sidebar that are significantly shorter.
|
||||
These do not compete in the same category, since their output is materially different.
|
||||
They are derived from the solutions above, but are still fascinating as concise utilities,
|
||||
so here is their progression, for the curious:
|
||||
|
||||
// 102
|
||||
I;O(O){putchar(O+48+39*(9<O));}main(l){for(;~(l=getchar());O(++I&15?~15:~37))O(l>>4),O(l&15);O(-38);}
|
||||
// 80
|
||||
O;main(l){while(~(l=getchar()))printf("%02x%c",l,++O&15?32:10);O&15&&puts("");}
|
||||
// 78
|
||||
O;main(l){for(;~l;(O=~(l=getchar())?printf("%02x ",l),-~O&15:!O)||puts(""));}
|
||||
// 77
|
||||
O;main(l){for(;~l;(O=~(l=getchar())?-~O&printf("%02x ",l)*5:!O)||puts(""));}
|
||||
// 76
|
||||
O;main(l){for(;~l;O||puts(&O))O=~(l=getchar())?-~O&printf("%02x ",l)*5:!O;}
|
||||
|
||||
It is possible to reduce the size of each of these by one by eliding the trailing newline.
|
||||
This was not reported above since the newline kept getting appended by processing software,
|
||||
and it is more interesting to remove characters by changing code than by filtering:
|
||||
|
||||
$ tr -d '\012' < 109.c | wc -c
|
||||
108
|
||||
$ tr -d '\012' < 76.c | wc -c
|
||||
75
|
||||
$ tr -d '\012' < 109.c | cc -o 108 -xc -
|
||||
$ verify 108
|
||||
$
|
||||
|
||||
An obfuscated hex dump has been done before:
|
||||
[1986/bright/bright.c](http://ioccc.org/1986/bright/bright.c) is similar in function,
|
||||
but it uses more characters in just setting up its obfuscation than this entire solution!
|
||||
|
||||
BIGGER SPOILER
|
||||
--------------
|
||||
|
||||
If you are unhappy with the way DEL (character 127) is handled,
|
||||
replace the cryptic expression `4<(4^l>>5)?l:46` with `32>l|l>126?46:l`.
|
||||
Both take the same number of characters, but the former is a bit more interesting.
|
||||
Bonus question: how does the first expression work?
|
||||
|
||||
BIGGEST SPOILER (and some history)
|
||||
----------------------------------
|
||||
|
||||
Technically, `char o[0];` is illegal (SS 6.7.6.2) according to ISO (N1570).
|
||||
And `char o[];` is a conditionally supported feature (SS 6.7.6.2, 6.10.8.3).
|
||||
However, it works in modern C implementations as an extension,
|
||||
including GCC, Clang and TCC, for X86 and ARM,
|
||||
on multiple operating systems (Linux, OSX, FreeBSD), so it is _functionally_ correct.
|
||||
MicroSoft Visual C++ does not allow `char o[]` or `char o[0]`,
|
||||
and implements its close relative `char o[1]`
|
||||
such that writing more than a single char will cause a fault, which is _technically_ correct.
|
||||
|
||||
But how does this work at all, even as an extension?
|
||||
`o[]` allocates one(!) byte in a zero-filled data area (formerly BSS).
|
||||
The UNIX-derived systems this code was run upon all place the
|
||||
storage of `O` and `o` into a zero-filled VM page with nothing following:
|
||||
thus, there are plenty of available and unused zero bytes following `O`, addressed via `o`,
|
||||
and this code only needs 17.
|
||||
This is _undefined_ behavior, but as shown, it is widely available.
|
||||
|
||||
The [1979 Seventh Edition UNIX][1] (v7) system pre-dates the IOCCC by several years,
|
||||
and the source code to `sh`(1) was a [significant inspiration for this contest][2].
|
||||
There are two C compilers present: `cc` written by Dennis Ritchie, and `pcc` written by Steven Johnson.
|
||||
The nested conditional expressions in 116 and smaller are too complex for `cc` ("Illegal conditional")
|
||||
but `pcc` handles them correctly, and neither compiler accepts `char o[]` or `char o[0]` nor puts the bytes in
|
||||
a zero-filled page (as a paged VM was not yet written for UNIX).
|
||||
|
||||
[1]: http://minnie.tuhs.org/cgi-bin/utree.pl
|
||||
[2]: http://ioccc.org/all/README
|
||||
[3]: http://www.computerworld.com.au/article/279011/a-z_programming_languages_bourne_shell_sh/?pp=4
|
||||
|
||||
More significant is that v7 `printf`(3) does not report the number of characters written,
|
||||
and therefore 111 compiles but does not work correctly;
|
||||
113 is the shortest code that compiles and runs correctly in Ancient UNIX.
|
||||
|
||||
> Interesting digression: v7 `printf` (`_doprnt`) was written in PDP-11 assembler.
|
||||
> It pre-dates `varargs.h`, and assembly was the only way to gain access to the variable argument types.
|
||||
> The first edition _The C Programming Language_, 1978, page 71, remarks:
|
||||
|
||||
>> By the way, there is no entirely satisfactory way to write a portable function
|
||||
>> that accepts a variable number of arguments, because there is no portable way
|
||||
>> for the called function to determine how many arguments where actually passed to it in a given call.
|
||||
>> ...
|
||||
>> `printf`, the most common C function with a variable number of arguments,
|
||||
>> ... is also non-portable and must be modified for different environments.
|
||||
|
||||
> It is fascinating to explore the roots of C through the history of the operating system
|
||||
> it was birthed within. C is often criticized as a difficult, inscrutable language,
|
||||
> but as this contest demonstrates, this is in parody.
|
||||
> _Shell-gol_ is one of those instances where someone [preferred a different language][3],
|
||||
> and (ab)used the preprocessor to re-mold C into something they found comfortable.
|
||||
> Most of the rest of the system, especially in the kernel,
|
||||
> are models of clarity and efficient expression.
|
||||
|
||||
TL;DR
|
||||
-----
|
||||
|
||||
So which version is the shortest, portable hex dump?
|
||||
|
||||
* 109 works with (most?) modern Unix-like systems and compilers, see example list above.
|
||||
* 111 works adds Microsoft, is standards-approved, and does not exploit undefined behavior.
|
||||
* 113 works on Ancient UNIX and the portable C compiler.
|
||||
* 119 works on all platforms, including the original Ritchie PDP-11 C compiler.
|
||||
|
||||
Coda
|
||||
----
|
||||
|
||||
Clearly, the smallest possible program violates modern best practice.
|
||||
It is not even possible to compile cleanly, but it will compile correctly.
|
||||
|
||||
Included is `prog.nowarn.c`, a modern C implementation that is -- perhaps -- the smallest,
|
||||
clean-compiling version using `clang` or `gcc` with `-Wall -pedantic`.
|
||||
Note that while this is larger than all but the original attempt,
|
||||
it will *not* work with the original Ritchie PDP-11 C compiler,
|
||||
since the expression within the ternary remains too complex.
|
||||
|
||||
Try
|
||||
|
||||
cat prog.c prog.nowarn.c
|
||||
|
||||
to compare the differences (`diff` is not helpful on a one-liner).
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
<!--
|
||||
(c) Copyright 1984-2018, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
|
||||
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
|
||||
|
||||
[judges]: http://www.ioccc.org/judges.html
|
||||
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
-->
|
||||
@@ -0,0 +1 @@
|
||||
char O,o[];main(l){for(;~l;O||puts(o))O=(O[o]=~(l=getchar())?4<(4^l>>5)?l:46:0)?-~O&printf("%02x ",l)*5:!O;}
|
||||
@@ -0,0 +1 @@
|
||||
int O;char o[17];int main(int l,char**v){for(;~l;O?O:puts(o))O=(O[o]=~(l=getchar())?4<(4^l>>5)?l:46:0)?-~O&printf("%02x ",l)*5:!O;return!v;}
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/bin/sh
|
||||
|
||||
hd=${HD:=prog}
|
||||
|
||||
cat $* |
|
||||
$hd |
|
||||
awk '
|
||||
BEGIN { nodup=1; group=1 }
|
||||
nodup {
|
||||
# suppress duplicate lines
|
||||
if ($0 == prev) {
|
||||
if (dots == 0)
|
||||
printf "%04x: . . .\n", off
|
||||
dots = off += 16
|
||||
next
|
||||
}
|
||||
prev = $0
|
||||
dots = 0
|
||||
}
|
||||
{
|
||||
# determine the number of bytes, rest is ascii
|
||||
nb = 16
|
||||
if (length($0) < 48 || length($16) != 2) {
|
||||
for (nb=1; nb<NF; ++nb)
|
||||
if (length($nb) != 2 || $nb !~ /[0-9a-f][0-9a-f]/)
|
||||
break
|
||||
--nb
|
||||
}
|
||||
}
|
||||
group {
|
||||
sz = 35
|
||||
hex = $1 $2 $3 $4 " " $5 $6 $7 $8 " " $9 $10 $11 $12 " " $13 $14 $15 $16
|
||||
if (nb < 16) hex = substr(hex, 1, nb*2+nb/4)
|
||||
}
|
||||
!group {
|
||||
sz = 47
|
||||
hex = substr($0, 0, nb*3-1)
|
||||
}
|
||||
{
|
||||
asc = substr($0, nb*3+1)
|
||||
printf "%04x: %-*.*s |%-16s|\n", off, sz, sz, hex, asc
|
||||
off += nb
|
||||
}'
|
||||
@@ -0,0 +1,310 @@
|
||||
#!/usr/bin/env make
|
||||
#
|
||||
# 2018 makefile
|
||||
#
|
||||
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
|
||||
# is licensed under:
|
||||
#
|
||||
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
|
||||
#
|
||||
# See: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
|
||||
################
|
||||
# tool locations
|
||||
################
|
||||
#
|
||||
SHELL= /bin/bash
|
||||
CP= cp
|
||||
CPP= cpp
|
||||
GUNZIP= gunzip
|
||||
BUNZIP2= bunzip2
|
||||
GZIP_PROG= gzip
|
||||
BZIP2= bzip2
|
||||
CURL= curl
|
||||
DD= dd
|
||||
LD= ld
|
||||
MAKE= make
|
||||
RM= rm
|
||||
SED= sed
|
||||
TAR= tar
|
||||
TRUE= true
|
||||
MKDIR= mkdir
|
||||
MV= mv
|
||||
TR= tr
|
||||
GREP= grep
|
||||
SORT= sort
|
||||
UNIQ= uniq
|
||||
|
||||
# Set X11_LIBDIR to the directory where the X11 library resides
|
||||
#
|
||||
#X11_LIBDIR= /usr/X11R6/lib
|
||||
#X11_LIBDIR= /usr/X11/lib
|
||||
X11_LIBDIR= /opt/X11/lib
|
||||
|
||||
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
|
||||
#
|
||||
#X11_INCDIR= /usr/X11R6/include
|
||||
#X11_INCDIR= /usr/X11/include
|
||||
X11_INCDIR= /opt/X11/include
|
||||
|
||||
# Compiler warnings
|
||||
#
|
||||
#CWARN=
|
||||
#CWARN= -Wall
|
||||
#CWARN= -Wall -Wextra
|
||||
CWARN= -Wall -Wextra ${CSILENCE}
|
||||
#CWARN= -Wall -Wextra -pedantic ${CSILENCE}
|
||||
#CWARN= -Wall -Wextra -Weverything
|
||||
#CWARN= -Wall -Wextra -Weverything -pedantic
|
||||
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
|
||||
|
||||
# Silence warnings that ${CWARN} would normally complain about
|
||||
#
|
||||
CSILENCE= -Wno-empty-body -Wno-parentheses -Wno-pointer-sign -Wno-char-subscripts -Wno-trigraphs -Wno-sign-compare
|
||||
#CSILENCE= -Wno-implicit-int
|
||||
|
||||
# compiler standard
|
||||
#
|
||||
#CSTD=
|
||||
#CSTD= -ansi
|
||||
CSTD= -std=c11
|
||||
|
||||
# compiler bit architecture
|
||||
#
|
||||
# Some entries require 32-bitness:
|
||||
# ARCH= -m32
|
||||
#
|
||||
# Some entries require 64-bitness:
|
||||
# ARCH= -m64
|
||||
#
|
||||
# By default we assume nothing:
|
||||
#
|
||||
ARCH=
|
||||
|
||||
# defines that are needed to compile
|
||||
#
|
||||
CDEFINE= -trigraphs -DW=\"keywords\" -DU=$(USAGE)
|
||||
#CDEFINE= -DIOCCC=25
|
||||
|
||||
# include files that are needed to compile
|
||||
#
|
||||
CINCLUDE=
|
||||
#CINCLUDE= -include stdlib.h
|
||||
#CINCLUDE= -include stdio.h
|
||||
#CINCLUDE= -include stdlib.h -include stdio.h
|
||||
#CINCLUDE= -I ${X11_INCDIR}
|
||||
|
||||
# optimization
|
||||
#
|
||||
# Most compiles will safely use -O2. Some can use only -O1 or -O.
|
||||
# A few compilers have broken optimizers or this entry make break
|
||||
# under those buggy optimizers and thus you may not want anything.
|
||||
# Reasonable compilers will allow for -O3.
|
||||
#
|
||||
#OPT=
|
||||
#OPT= -O
|
||||
#OPT= -O1
|
||||
#OPT= -O2
|
||||
OPT= -O3
|
||||
|
||||
# default flags for ANSI C compilation
|
||||
#
|
||||
CFLAGS= ${CSTD} ${CWARN} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
|
||||
|
||||
# Libraries needed to build
|
||||
#
|
||||
LIBS=
|
||||
#LIBS= -L ${X11_LIBDIR}
|
||||
|
||||
# ANSI compiler
|
||||
#
|
||||
# Set CC to the name of your ANSI compiler.
|
||||
#
|
||||
# Some entries seem to need gcc. If you have gcc, set
|
||||
# both CC and MAY_NEED_GCC to gcc.
|
||||
#
|
||||
# If you do not have gcc, set CC to the name of your ANSI compiler, and
|
||||
# set MAY_NEED_GCC to either ${CC} (and hope for the best) or to just :
|
||||
# to disable such programs.
|
||||
#
|
||||
CC= cc
|
||||
#CC=clang
|
||||
MAY_NEED_GCC= gcc
|
||||
|
||||
|
||||
##############################
|
||||
# Special flags for this entry
|
||||
##############################
|
||||
#
|
||||
OBJ= prog.o
|
||||
DATA= keywords
|
||||
EXTRA_DATA= ansi c++11 c++14 c++98 c11 c99 discrepancies \
|
||||
test01.c test02.c test03.c test04.c test05.c test06.c test07.c \
|
||||
test08.c test09.c test10.c test11.c test12.c test13.c test14.c \
|
||||
iocccbug01.c iocccbug02.c iocccbug03.c iocccbug04.c iocccbug05.c \
|
||||
iocccbug06.c results results.k src.doc.rot13 patch tac.man README \
|
||||
ioc_without_quote
|
||||
UTILITIES= unob.sh tokenfix spotcheck spotdiff freqcount
|
||||
TARGET= prog
|
||||
#
|
||||
ALT_OBJ=
|
||||
ALT_TARGET=
|
||||
##
|
||||
USAGE="\"prog [-tcksri] < file.c\ntokenize and count stdin\n\t-t\ttokens only\n\t-c\tcompatible counts\n\t-k\tkeep comments\n\t-s\tsuppress output\n\t-r\treserved words count as 1\n\t-i\tioccc count only\n\""
|
||||
|
||||
#################
|
||||
# build the entry
|
||||
#################
|
||||
#
|
||||
all: ${TARGET} ${DATA} ${UTILITIES}
|
||||
@${TRUE}
|
||||
|
||||
prog: prog.c keywords
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
tac: tac.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
# alternative executable
|
||||
#
|
||||
alt: ${ALT_TARGET}
|
||||
@${TRUE}
|
||||
|
||||
# data files
|
||||
#
|
||||
data: ${DATA}
|
||||
@${TRUE}
|
||||
|
||||
# keywords: c11
|
||||
keywords: ioccc.kw.freq mkkeywords
|
||||
./mkkeywords $< > keywords
|
||||
|
||||
fixed_iocccsize: fixed_iocccsize.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
test: prog tac runtest fixed_iocccsize ${EXTRA_DATA}
|
||||
-./runtest | diff - results
|
||||
-opt=kcrs ./runtest | diff - results.k
|
||||
-opt=rs prog=tac ./runtest | diff - results
|
||||
-opt=rsk prog=tac ./runtest | diff - results.k
|
||||
./fixed_iocccsize -rs < prog.c
|
||||
./tac -rs prog.c
|
||||
|
||||
###############
|
||||
# utility rules
|
||||
###############
|
||||
#
|
||||
everything: all alt
|
||||
|
||||
clean:
|
||||
${RM} -f ${OBJ} ${ALT_OBJ}
|
||||
|
||||
clobber: clean
|
||||
${RM} -f ${TARGET} ${ALT_TARGET}
|
||||
${RM} -f fixed_iocccsize tac keywords iocccsize
|
||||
@-if [ -e sandwich ]; then \
|
||||
${RM} -f sandwich; \
|
||||
echo 'ate sandwich'; \
|
||||
fi
|
||||
|
||||
nuke: clobber
|
||||
@${TRUE}
|
||||
|
||||
dist_clean: nuke
|
||||
@${TRUE}
|
||||
|
||||
install:
|
||||
@echo "Surely you are performing, Dr. May!"
|
||||
@${TRUE}
|
||||
|
||||
# backwards compatibility
|
||||
#
|
||||
build: all
|
||||
@${TRUE}
|
||||
|
||||
|
||||
##################
|
||||
# 133t hacker rulz
|
||||
##################
|
||||
#
|
||||
love:
|
||||
@echo 'not war?'
|
||||
@${TRUE}
|
||||
|
||||
haste:
|
||||
$(MAKE) waste
|
||||
@${TRUE}
|
||||
|
||||
waste:
|
||||
@echo 'haste'
|
||||
@${TRUE}
|
||||
|
||||
make:
|
||||
@echo 'Attend a maker faire'
|
||||
@${TRUE}
|
||||
|
||||
easter_egg:
|
||||
@echo you expected to often mis-understand this $${RANDOM} magic
|
||||
@echo chongo '<was here>' "/\\oo/\\"
|
||||
@echo Eggy
|
||||
|
||||
fabricate fashion form frame manufacture produce: make
|
||||
@${TRUE}
|
||||
|
||||
sandwich:
|
||||
@if [ `id -u` -eq 0 ]; then \
|
||||
echo 'Okay.'; \
|
||||
echo $${RANDOM}`date +%s`$${RANDOM} > $@; \
|
||||
else \
|
||||
echo 'What? Make it yourself.'; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
# Understand the history of the Homebrew Computer Club
|
||||
# as well as the West Coast Computer Faire and
|
||||
# you might be confused different. :-)
|
||||
#
|
||||
supernova: nuke
|
||||
@-if [ -r .code_anal ]; then \
|
||||
${RM} -f .code_anal_v6; \
|
||||
else \
|
||||
echo "planet deniers, like some members of the IAU, are so cute when they try to defend their logic"; \
|
||||
fi
|
||||
@echo A $@ helps ${MAKE} the elements that help form planets
|
||||
@${TRUE}
|
||||
|
||||
deep_magic:
|
||||
@-if [ -r .code_anal ]; then \
|
||||
ccode_analysis --deep_magic 3a3fabb90892eeb2f610ae0f74a35a970060665a063ab702bd686c17c4ae07f6 --FNV1a_hash_256_bit "prog"; \
|
||||
else \
|
||||
echo "Wrong! Do it again!"; \
|
||||
sleep 2; \
|
||||
echo "Wrong! Do it again!"; \
|
||||
sleep 2; \
|
||||
echo "Wrong! Do it again!"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
|
||||
magic: deep_magic
|
||||
@-if [ -r .code_anal ]; then \
|
||||
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_256_bit "prog"; \
|
||||
else \
|
||||
echo "If you don't eat yer meat, you can't have any pudding!"; \
|
||||
echo "How can you have any pudding if you don't eat yer meat?!"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
|
||||
# The IOCCC resident astronomer states
|
||||
#
|
||||
charon: supernova
|
||||
@echo $@ is a dwarf planet
|
||||
@echo dwarf is a type of planet
|
||||
@echo $@ is a planet
|
||||
|
||||
pluto: supernova
|
||||
${MAKE} charon
|
||||
@echo $@ is a dwarf planet
|
||||
@echo dwarf is a type of planet
|
||||
@echo $@ is a planet
|
||||
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
|
||||
@@ -0,0 +1,71 @@
|
||||
tac comes with a small suite of support programs to test and validate against.
|
||||
Untar tests and variations in the same dir as the sources,
|
||||
or change runtest and unob.sh to look elsewhere for the keyword and test files.
|
||||
|
||||
keywords is a critical file, created from ioccc.kw.freq by mkkeywords.
|
||||
Only ioccc.kw.freq produces results compatible with iocccsize.c;
|
||||
however, any of the variations can be used instead:
|
||||
|
||||
mkkeywords c11 > keywords
|
||||
|
||||
unob.sh uses the same input file as mkkeywords to control spaces after keywords.
|
||||
The script allows an environment variable, KW, to override this.
|
||||
Use it simply:
|
||||
|
||||
unob.sh prog.c | less
|
||||
unob.sh -p prog.c | less
|
||||
KW=c11 unob.sh prog.c | less
|
||||
|
||||
To handle obscure command line defines, use the environment variable DEF:
|
||||
|
||||
DEF="-D'g(o)'='goto o;'" KW=c11 unob.sh -p prog.c | less
|
||||
|
||||
It does an amazingly good job for such a simple script.
|
||||
|
||||
Manifest
|
||||
|
||||
prog.c the reason for this README
|
||||
keywords the file #included in prog.c, output of mkkeywords
|
||||
mkkeywords reads one of the files from variations, produces string for prog.c
|
||||
ioccc.kw.freq keywords used by iocccsize, sorted by frequency in 201x ioccc winners
|
||||
unob.sh a more robust unobfuscation script; requires variations/c11 in cur dir
|
||||
tokenfix patches up prog -t output for ::, >>>, ...
|
||||
src.doc.rot13 the answers, or at least significant help
|
||||
tac.c more clearly written code, offered as a replacement of iocccsize.c
|
||||
patch fixes single quotes in iocccsize.c, adds #ifndef, removes "I"
|
||||
fixed_iocccsize.c iocccsize with patch applied, and nop -c argument added
|
||||
|
||||
tests/*
|
||||
runtest script to run the tests; ./runtest | diff results -
|
||||
results results without -k
|
||||
results.k results with -k; opt=kcrs ./runtest | diff results.k -
|
||||
test*.c various test cases looking for compatability
|
||||
iocccbug*.c various test cases demonstrating problems with iocccsize
|
||||
spotcheck script to test a lot of files vs iocccsize
|
||||
spotdiff summarize the results of spotcheck, showing only differences
|
||||
discrepancies text file of the differences found using all the ioccc winning entries
|
||||
|
||||
to test prog:
|
||||
|
||||
runtest | diff - results
|
||||
opt=kcrs runtest | diff - results.k
|
||||
find ~/src/obc -type f -a -name "*.c" | xargs spotcheck prog
|
||||
[ | spotdiff | diff -bw - discrepancies ]
|
||||
|
||||
to test tac:
|
||||
|
||||
prog=tac runtest | diff - results
|
||||
prog=tac opt=krs runtest | diff - results.k
|
||||
find ~/src/obc -type f -a -name "*.c" | xargs spotcheck tac
|
||||
|
||||
variations/* as described in the remarks, and in each file below
|
||||
ansi
|
||||
c++11
|
||||
c++14
|
||||
c++98
|
||||
c11
|
||||
c99
|
||||
java8
|
||||
kandr
|
||||
kandr2
|
||||
v7unix
|
||||
@@ -0,0 +1,46 @@
|
||||
$ ANS X3.159-1989, SS 3.1.1, pg 20, SS 3.8, pg 86
|
||||
#define
|
||||
#elif
|
||||
#else
|
||||
#endif
|
||||
#error
|
||||
#if
|
||||
#ifdef
|
||||
#ifndef
|
||||
#include
|
||||
#line
|
||||
#pragma
|
||||
#undef
|
||||
auto
|
||||
break
|
||||
case
|
||||
char
|
||||
const
|
||||
continue
|
||||
default
|
||||
defined
|
||||
do
|
||||
double
|
||||
else
|
||||
enum
|
||||
extern
|
||||
float
|
||||
for
|
||||
goto
|
||||
if
|
||||
int
|
||||
long
|
||||
register
|
||||
return
|
||||
short
|
||||
signed
|
||||
sizeof
|
||||
static
|
||||
struct
|
||||
switch
|
||||
typedef
|
||||
union
|
||||
unsigned
|
||||
void
|
||||
volatile
|
||||
while
|
||||
@@ -0,0 +1,99 @@
|
||||
$ N3337 2012-01-16 $
|
||||
alignas
|
||||
alignof
|
||||
and
|
||||
and_eq
|
||||
asm
|
||||
auto
|
||||
bitand
|
||||
bitor
|
||||
bool
|
||||
break
|
||||
case
|
||||
catch
|
||||
char
|
||||
char16_t
|
||||
char32_t
|
||||
class
|
||||
compl
|
||||
const
|
||||
constexpr
|
||||
const_cast
|
||||
continue
|
||||
decltype
|
||||
default
|
||||
delete
|
||||
do
|
||||
double
|
||||
dynamic_cast
|
||||
else
|
||||
enum
|
||||
explicit
|
||||
export
|
||||
extern
|
||||
false
|
||||
float
|
||||
for
|
||||
friend
|
||||
goto
|
||||
if
|
||||
inline
|
||||
int
|
||||
long
|
||||
mutable
|
||||
namespace
|
||||
new
|
||||
noexcept
|
||||
not
|
||||
not_eq
|
||||
nullptr
|
||||
operator
|
||||
or
|
||||
or_eq
|
||||
private
|
||||
protected
|
||||
public
|
||||
register
|
||||
reinterpret_cast
|
||||
return
|
||||
short
|
||||
signed
|
||||
sizeof
|
||||
static
|
||||
static_assert
|
||||
static_cast
|
||||
struct
|
||||
switch
|
||||
template
|
||||
this
|
||||
thread_local
|
||||
throw
|
||||
true
|
||||
try
|
||||
typedef
|
||||
typeid
|
||||
typename
|
||||
union
|
||||
unsigned
|
||||
using
|
||||
virtual
|
||||
void
|
||||
volatile
|
||||
wchar_t
|
||||
while
|
||||
xor
|
||||
xor_eq
|
||||
#if
|
||||
#elif
|
||||
#else
|
||||
#endif
|
||||
defined
|
||||
#ifdef
|
||||
#ifndef
|
||||
#define
|
||||
#undef
|
||||
#include
|
||||
#line
|
||||
#error
|
||||
#pragma
|
||||
_Pragma
|
||||
@@ -0,0 +1,99 @@
|
||||
$ N4296 2014-11-09 Working Draft, Standard for Programming Language C++ $
|
||||
alignas
|
||||
alignof
|
||||
and
|
||||
and_eq
|
||||
asm
|
||||
auto
|
||||
bitand
|
||||
bitor
|
||||
bool
|
||||
break
|
||||
case
|
||||
catch
|
||||
char
|
||||
char16_t
|
||||
char32_t
|
||||
class
|
||||
compl
|
||||
const
|
||||
constexpr
|
||||
const_cast
|
||||
continue
|
||||
decltype
|
||||
default
|
||||
delete
|
||||
do
|
||||
double
|
||||
dynamic_cast
|
||||
else
|
||||
enum
|
||||
explicit
|
||||
export
|
||||
extern
|
||||
false
|
||||
float
|
||||
for
|
||||
friend
|
||||
goto
|
||||
if
|
||||
inline
|
||||
int
|
||||
long
|
||||
mutable
|
||||
namespace
|
||||
new
|
||||
noexcept
|
||||
not
|
||||
not_eq
|
||||
nullptr
|
||||
operator
|
||||
or
|
||||
or_eq
|
||||
private
|
||||
protected
|
||||
public
|
||||
register
|
||||
reinterpret_cast
|
||||
return
|
||||
short
|
||||
signed
|
||||
sizeof
|
||||
static
|
||||
static_assert
|
||||
static_cast
|
||||
struct
|
||||
switch
|
||||
template
|
||||
this
|
||||
thread_local
|
||||
throw
|
||||
true
|
||||
try
|
||||
typedef
|
||||
typeid
|
||||
typename
|
||||
union
|
||||
unsigned
|
||||
using
|
||||
virtual
|
||||
void
|
||||
volatile
|
||||
wchar_t
|
||||
while
|
||||
xor
|
||||
xor_eq
|
||||
#if
|
||||
#elif
|
||||
#else
|
||||
#endif
|
||||
defined
|
||||
#ifdef
|
||||
#ifndef
|
||||
#define
|
||||
#undef
|
||||
#include
|
||||
#line
|
||||
#error
|
||||
#pragma
|
||||
_Pragma
|
||||
@@ -0,0 +1,88 @@
|
||||
$ ISO/IEC 14882:1998(E) 2.11 $
|
||||
and
|
||||
and_eq
|
||||
asm
|
||||
auto
|
||||
bitand
|
||||
bitor
|
||||
bool
|
||||
break
|
||||
case
|
||||
catch
|
||||
char
|
||||
class
|
||||
compl
|
||||
const
|
||||
const_cast
|
||||
continue
|
||||
default
|
||||
delete
|
||||
do
|
||||
double
|
||||
dynamic_cast
|
||||
else
|
||||
enum
|
||||
explicit
|
||||
export
|
||||
extern
|
||||
false
|
||||
float
|
||||
for
|
||||
friend
|
||||
goto
|
||||
if
|
||||
inline
|
||||
int
|
||||
long
|
||||
mutable
|
||||
namespace
|
||||
new
|
||||
not
|
||||
not_eq
|
||||
operator
|
||||
or
|
||||
or_eq
|
||||
private
|
||||
protected
|
||||
public
|
||||
register
|
||||
reinterpret_cast
|
||||
return
|
||||
short
|
||||
signed
|
||||
sizeof
|
||||
static
|
||||
static_cast
|
||||
struct
|
||||
switch
|
||||
template
|
||||
this
|
||||
throw
|
||||
true
|
||||
try
|
||||
typedef
|
||||
typeid
|
||||
typename
|
||||
union
|
||||
unsigned
|
||||
using
|
||||
virtual
|
||||
void
|
||||
volatile
|
||||
wchar_t
|
||||
while
|
||||
xor
|
||||
xor_eq
|
||||
#if
|
||||
#elif
|
||||
#else
|
||||
#endif
|
||||
defined
|
||||
#ifdef
|
||||
#ifndef
|
||||
#define
|
||||
#undef
|
||||
#include
|
||||
#line
|
||||
#error
|
||||
#pragma
|
||||
@@ -0,0 +1,58 @@
|
||||
$ C11: ISO/IEC 9899:201x, April 12, 2012 Committee Draft, N1570 $
|
||||
#define
|
||||
#elif
|
||||
#else
|
||||
#endif
|
||||
#error
|
||||
#if
|
||||
#ifdef
|
||||
#ifndef
|
||||
#include
|
||||
#line
|
||||
#pragma
|
||||
#undef
|
||||
_Alignas
|
||||
_Alignof
|
||||
_Atomic
|
||||
_Bool
|
||||
_Complex
|
||||
_Generic
|
||||
_Imaginary
|
||||
_Noreturn
|
||||
_Static_assert
|
||||
_Thread_local
|
||||
auto
|
||||
break
|
||||
case
|
||||
char
|
||||
const
|
||||
continue
|
||||
default
|
||||
defined
|
||||
do
|
||||
double
|
||||
else
|
||||
enum
|
||||
extern
|
||||
float
|
||||
for
|
||||
goto
|
||||
if
|
||||
inline
|
||||
int
|
||||
long
|
||||
register
|
||||
restrict
|
||||
return
|
||||
short
|
||||
signed
|
||||
sizeof
|
||||
static
|
||||
struct
|
||||
switch
|
||||
typedef
|
||||
union
|
||||
unsigned
|
||||
void
|
||||
volatile
|
||||
while
|
||||
@@ -0,0 +1,50 @@
|
||||
$ C99: ISO/IEC 9899:1999(E), pg 50 $
|
||||
#define
|
||||
#elif
|
||||
#else
|
||||
#endif
|
||||
#error
|
||||
#if
|
||||
#ifdef
|
||||
#ifndef
|
||||
#include
|
||||
#line
|
||||
#pragma
|
||||
#undef
|
||||
_Bool
|
||||
_Complex
|
||||
_Imaginary
|
||||
auto
|
||||
break
|
||||
case
|
||||
char
|
||||
const
|
||||
continue
|
||||
default
|
||||
do
|
||||
double
|
||||
else
|
||||
enum
|
||||
extern
|
||||
float
|
||||
for
|
||||
goto
|
||||
if
|
||||
inline
|
||||
int
|
||||
long
|
||||
register
|
||||
restrict
|
||||
return
|
||||
short
|
||||
signed
|
||||
sizeof
|
||||
static
|
||||
struct
|
||||
switch
|
||||
typedef
|
||||
union
|
||||
unsigned
|
||||
void
|
||||
volatile
|
||||
while
|
||||
@@ -0,0 +1,62 @@
|
||||
The values below are the field-by-field difference iocccsize - ioc.
|
||||
(>0 means iocccsize counted more than ioc, <0 ioc counted more)
|
||||
cl: lines, cw: words, cc: chars, ci: rule2, ts: saved, kw: keywords, ks: kw_saved
|
||||
|
||||
cl 0 cw -4 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/1986/pawka.c
|
||||
cl -45 cw -55 cc -617 ci -463 ts -85 kw -26 ks -69 src/obc/1990/theorem.c
|
||||
ioc is correct; cl is correct even in compat (91) due to comments eating newlines
|
||||
iocccsize fails at "z;/*/", eating everything until the following "/**/main("
|
||||
looks to be due to mis-identification of a comment closing block as opening block
|
||||
cl 0 cw -2 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/1991/westley.c
|
||||
cl 0 cw -3 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/1992/adrian.c
|
||||
cl 0 cw -3 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/1992/adrian.orig.c
|
||||
cl 0 cw -1 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/1994/shapiro.c
|
||||
cl 0 cw -2 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/1996/gandalf.c
|
||||
cl 0 cw -1 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/1996/schweikh1.c
|
||||
cl 0 cw -2 cc 0 ci -2 ts 0 kw 1 ks 2 src/obc/1998/df.c
|
||||
iocccsize counts as keyword __##int##__, and saving two characters
|
||||
but int is not a plausible keyword
|
||||
cl 0 cw -1 cc 3 ci 2 ts 1 kw 0 ks 0 src/obc/2001/herrmann1.c
|
||||
the text:
|
||||
d M Y(O)/* state to */
|
||||
d
|
||||
counts as cw 3 in iocccsize, but this is clearly 4
|
||||
and the cc,ci,ts is due entirely to:
|
||||
/*/*/*/*/*/ /*/*/
|
||||
E E /*/*/*/*/*/,/) F
|
||||
which reduces to:
|
||||
* E E * ,/) F
|
||||
but iocccsize counts this as * E E *,/) F, whereas ANSI C says comments are
|
||||
replaced with a single space equivalent (non-portable token-paste with comments)
|
||||
cl 0 cw -2 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/2004/arachnid.c
|
||||
cl 0 cw -2 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/2004/arachnid.orig.c
|
||||
cl 0 cw 0 cc 0 ci -4 ts 0 kw 2 ks 4 src/obc/2004/hoyle.c
|
||||
cl 0 cw 0 cc 0 ci -4 ts 0 kw 2 ks 4 src/obc/2004/hoyle.orig.c
|
||||
ioccccsize counts as two keywords the token-pasted int##if (e.g int1)
|
||||
thus the kw 2, and another bug in iocccsize counts #if as a keyword to 1
|
||||
thus saving 2 bytes on int, and 2 more on #if, when neither is a plausible keyword
|
||||
cl 0 cw -1 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/2004/omoikane.c
|
||||
cl 0 cw -1 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/2005/chia/chia.c
|
||||
cl 0 cw -1 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/2005/mikeash/mikeash.c
|
||||
cl 0 cw 0 cc 0 ci 1 ts 1 kw 0 ks 0 src/obc/2005/toledo/toledo.c
|
||||
cl 0 cw 0 cc 0 ci 1 ts 1 kw 0 ks 0 src/obc/2005/toledo/toledo2.c
|
||||
cl 0 cw 0 cc 0 ci 1 ts 1 kw 0 ks 0 src/obc/2005/toledo/toledo3.c
|
||||
these three discrepancies are due to backslash-newline of longjm\p --
|
||||
at exactly the 521 byte line length boundary (which is arbitrary)
|
||||
ioc is correct, because it has no line length limit
|
||||
cl 0 cw -4 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/2011/akari/akari.c
|
||||
cl 0 cw -7 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/2011/hamaji/hamaji.c
|
||||
cl 0 cw -4 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/2012/endoh1/endoh1.c
|
||||
cl 0 cw -3 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/2012/endoh1/endoh1_color.c
|
||||
cl 0 cw -1 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/2012/endoh1/endoh1_deobfuscate.c
|
||||
cl 0 cw -2 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/2012/omoikane/nyaruko.c
|
||||
cl 0 cw 0 cc 0 ci -3 ts 0 kw 1 ks 3 src/obc/2013/cable2/cable2.c
|
||||
this is due to token-pasting of _##char; iocccsize counts this as a keyword
|
||||
but it is a pre-processor token-pasted string of the arg to Y() and char
|
||||
rendering this not a keyword, even in disguise
|
||||
cl 0 cw -2 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/2013/endoh4/endoh4.c
|
||||
cl 0 cw -2 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/2013/misaka/misaka.c
|
||||
cl 0 cw -1 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/2014/endoh2/prog.c
|
||||
cl 0 cw -4 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/2014/maffiodo1/prog.c
|
||||
cl 0 cw -4 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/2014/maffiodo1/prog.orig.c
|
||||
cl 0 cw -1 cc 0 ci 0 ts 0 kw 0 ks 0 src/obc/2014/sinon/prog.c
|
||||
@@ -0,0 +1,637 @@
|
||||
/*
|
||||
* iocccsize - IOCCC Source Size Tool
|
||||
*
|
||||
* This IOCCC size tool source file is version 2017-12-25-v25.
|
||||
*
|
||||
* "You are not expected to understand this" :-)
|
||||
*
|
||||
* Public Domain 1992, 2015 by Anthony Howe. All rights released.
|
||||
* With IOCCC minor mods in 2013-2017 by chongo (Landon Curt Noll) ^oo^
|
||||
*
|
||||
* SYNOPSIS
|
||||
*
|
||||
* ioccc [-kirs] < input
|
||||
*
|
||||
* -k keep comment blocks
|
||||
* -i IOCCC size rule (overall size, modified)
|
||||
* -r count C reserved words as 1 byte
|
||||
* -s suppress source output, write only the IOCCC 2nd size count
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Taking input from standard input, apply the IOCCC Source Size Rule
|
||||
* for 2001. The program's official length is written to standard error.
|
||||
* Also filter out C comment blocks (-k to keep) sending the modified
|
||||
* source to standard output.
|
||||
*
|
||||
* The 2001 Source Size Rule was:
|
||||
*
|
||||
* Your entry must be <= 4096 bytes in length. The number of octets
|
||||
* excluding whitespace (tab, space, newline, form-feed, return), and
|
||||
* excluding any ';', '{' or '}' followed by whitespace or end of file,
|
||||
* must be <= 2048.
|
||||
*
|
||||
* 2013 Source Size Rule is (-r):
|
||||
*
|
||||
* Your entry must be <= 4096 bytes in length. The number of octets
|
||||
* excluding whitespace (tab, space, newline, form-feed, return), and
|
||||
* excluding any ';', '{' or '}' followed by whitespace or end of file,
|
||||
* and where C reserved words, including a subset of preprocessor words,
|
||||
* count as 1 byte, must be <= 2053 (first prime after 2048).
|
||||
*/
|
||||
|
||||
/*
|
||||
* The official IOCCC rule 2 secondary limit on C code size
|
||||
*
|
||||
* The IOCCC size tool should be compiled as:
|
||||
*
|
||||
* cc -pedantic -Wall -std=c99 iocccsize.c -o iocccsize
|
||||
*
|
||||
* This tool computes a 2nd size C code. To check your program source
|
||||
* against the 2nd limit of rule 2, use the -i command line option.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* ./iocccsize -i < prog.c
|
||||
*
|
||||
* The IOCCC size tool, when using the -i option, may be summarized as:
|
||||
*
|
||||
* The size tool counts C language keywords (primary, secondary, and
|
||||
* selected preprocessor keywords) as 1. The size tool counts all
|
||||
* other octets as 1 excluding ASCII whitespace, and excluding any
|
||||
* ';', '{' or '}' followed by ASCII whitespace, and excluding any
|
||||
* ';', '{' or '}' octet immediately before the end of file.
|
||||
*
|
||||
* ASCII whitespace includes ASCII tab, ASCII space, ASCII newline,
|
||||
* ASCII form-feed, and ASCII carriage return.
|
||||
*
|
||||
* In cases where the above summary and the algorithm implemented by
|
||||
* the IOCCC size tool source code conflict, the algorithm implemented
|
||||
* by the IOCCC size tool source code is preferred by the judges.
|
||||
*
|
||||
* See the current IOCCC rules and guidelines for more information.
|
||||
* In particular, see the current IOCCC size rule for information about
|
||||
* the maximum value that this tool should print for an entry to be valid.
|
||||
*/
|
||||
|
||||
/*
|
||||
* IOCCC Judge's remarks:
|
||||
*
|
||||
* This code contains undocumented features. On the other hand, this code
|
||||
* is RTFS (for certain values of RTFS). One might say that this code
|
||||
* perfectly documents itself. :-)
|
||||
*
|
||||
* Many thanks to Anthony Howe for taking the time to put his OCD
|
||||
* (Obfuscated Coding Determination) into this code!
|
||||
*/
|
||||
|
||||
/*
|
||||
* HINT: The algorithm implemented by this code may or not be obfuscated.
|
||||
* The algorithm may not or may appear to be obfuscated.
|
||||
*
|
||||
* In particular:
|
||||
*
|
||||
* We did not invent the algorithm.
|
||||
* The algorithm consistently finds Obfuscation.
|
||||
* The algorithm killed Obfuscation.
|
||||
* The algorithm is banned in C.
|
||||
* The algorithm is from Bell Labs in Jersey.
|
||||
* The algorithm constantly finds Obfuscation.
|
||||
* This is not the algorithm.
|
||||
* This is close.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#define FLAG_SILENCE 1
|
||||
#define FLAG_KEEP 2
|
||||
#define FLAG_RESERVED 4
|
||||
#define FLAG_IOCCC 8
|
||||
#define FLAG_SILLY_C 16
|
||||
#define FLAG_SILLY_H 32
|
||||
|
||||
#define BUFFER_SIZE 521
|
||||
#define MAX_SIZE 4096 /* IOCCC Rule 2 */
|
||||
#define MAX_COUNT 2053 /* IOCCC Rule 2 */
|
||||
|
||||
static char usage[] =
|
||||
"usage: ioccc [-kirsch] < prog.c\n"
|
||||
"\n"
|
||||
"-k\t\tkeep block comments\n"
|
||||
"-i\t\tprint official secondary IOCCC size to stdout\n"
|
||||
"\t\tmax.size warnings to stderr, NOTE: implies -r -s\n"
|
||||
"-r\t\tcount C reserved words as 1 byte\n"
|
||||
"-s\t\tsuppress source output, write only the official size\n"
|
||||
"-c\t\tan undocumented feature\n"
|
||||
"-h\t\tyet another undocumented feature\n"
|
||||
;
|
||||
|
||||
#define STRLEN(s) (sizeof (s)-1)
|
||||
|
||||
typedef struct {
|
||||
size_t length;
|
||||
const char *word;
|
||||
} Word;
|
||||
|
||||
/*
|
||||
* C reserved words, plus a few #preprocessor tokens, that count as 1
|
||||
*
|
||||
* NOTE: For a good list of reserved words in C, see:
|
||||
*
|
||||
* http://www.bezem.de/pdf/ReservedWordsInC.pdf
|
||||
*
|
||||
* by Johan Bezem of JB Enterprises:
|
||||
*
|
||||
* See http://www.bezem.de/en/
|
||||
*/
|
||||
/*
|
||||
* The following editorial plea expresses a view shared by more than zero
|
||||
* IOCCC judges. It may not represent the opinion of all those involved
|
||||
* with this code nor the International Obfuscated C Code Contest as a whole:
|
||||
*
|
||||
* The long list of reserved words below should be a source
|
||||
* of embarrassment to some of those involved in standardizing C.
|
||||
* The growing list of reserved words, along with an expanding set of
|
||||
* linguistic inventions has the appearance of feature
|
||||
* creep that, if left unchecked, risks turning a beautifully elegant
|
||||
* language into a steaming pile of biological excretion.
|
||||
*
|
||||
* The history of the IOCCC has taught us that even minor changes
|
||||
* to the language are not always well understood by compiler writers,
|
||||
* let alone the standards body who publishes them. We have enormous
|
||||
* sympathy for C compiler writers who must keep up with the creeping
|
||||
* featurism. We are aware of some C standards members who share
|
||||
* these concerns. Alas, they seem to be a minority.
|
||||
*
|
||||
* The C standards body as a whole, before they emit yet more mountains of new
|
||||
* standardese, might wish consider the option of moth-balling their committee.
|
||||
* Or if they must produce a new standard, consider naming whatever
|
||||
* follows c11 as CNC (C's Not C). :-)
|
||||
*/
|
||||
static Word cwords[] = {
|
||||
/* Yes Virginia, we left #define off the list on purpose! */
|
||||
{ STRLEN("#elif"), "#elif" },
|
||||
{ STRLEN("#else"), "#else" },
|
||||
{ STRLEN("#endif"), "#endif" },
|
||||
{ STRLEN("#error"), "#error" },
|
||||
{ STRLEN("#ident"), "#ident" },
|
||||
{ STRLEN("#if"), "#if" },
|
||||
{ STRLEN("#ifdef"), "#ifdef" },
|
||||
{ STRLEN("#ifndef"), "#ifndef" }, /* XXX bugfix */
|
||||
{ STRLEN("#include"), "#include" },
|
||||
{ STRLEN("#line"), "#line" },
|
||||
{ STRLEN("#pragma"), "#pragma" },
|
||||
{ STRLEN("#sccs"), "#sccs" },
|
||||
{ STRLEN("#warning"), "#warning" },
|
||||
/**/
|
||||
{ STRLEN("_Alignas"), "_Alignas" },
|
||||
{ STRLEN("_Alignof"), "_Alignof" },
|
||||
{ STRLEN("_Atomic"), "_Atomic" },
|
||||
{ STRLEN("_Bool"), "_Bool" },
|
||||
{ STRLEN("_Complex"), "_Complex" },
|
||||
{ STRLEN("_Generic"), "_Generic" },
|
||||
{ STRLEN("_Imaginary"), "_Imaginary" },
|
||||
{ STRLEN("_Noreturn"), "_Noreturn" },
|
||||
{ STRLEN("_Pragma"), "_Pragma" },
|
||||
{ STRLEN("_Static_assert"), "_Static_assert" },
|
||||
{ STRLEN("_Thread_local"), "_Thread_local" },
|
||||
/*
|
||||
* this comment is not expected to understand itself
|
||||
*/
|
||||
{ STRLEN("alignas"), "alignas" },
|
||||
{ STRLEN("alignof"), "alignof" },
|
||||
{ STRLEN("and"), "and" },
|
||||
{ STRLEN("and_eq"), "and_eq" },
|
||||
{ STRLEN("auto"), "auto" },
|
||||
{ STRLEN("bitand"), "bitand" },
|
||||
{ STRLEN("bitor"), "bitor" },
|
||||
{ STRLEN("bool"), "bool" },
|
||||
{ STRLEN("break"), "break" },
|
||||
{ STRLEN("case"), "case" },
|
||||
{ STRLEN("char"), "char" },
|
||||
{ STRLEN("compl"), "compl" },
|
||||
{ STRLEN("const"), "const" },
|
||||
{ STRLEN("continue"), "continue" },
|
||||
{ STRLEN("default"), "default" },
|
||||
{ STRLEN("do"), "do" },
|
||||
{ STRLEN("double"), "double" },
|
||||
{ STRLEN("else"), "else" },
|
||||
{ STRLEN("enum"), "enum" },
|
||||
{ STRLEN("extern"), "extern" },
|
||||
{ STRLEN("false"), "false" },
|
||||
{ STRLEN("float"), "float" },
|
||||
{ STRLEN("for"), "for" },
|
||||
{ STRLEN("goto"), "goto" },
|
||||
/* { STRLEN("I"), "I" }, */ /* XXX seriously? */
|
||||
{ STRLEN("if"), "if" },
|
||||
{ STRLEN("inline"), "inline" },
|
||||
{ STRLEN("int"), "int" },
|
||||
{ STRLEN("long"), "long" },
|
||||
{ STRLEN("noreturn"), "noreturn" },
|
||||
{ STRLEN("not"), "not" },
|
||||
{ STRLEN("not_eq"), "not_eq" },
|
||||
{ STRLEN("or"), "or" },
|
||||
{ STRLEN("or_eq"), "or_eq" },
|
||||
{ STRLEN("register"), "register" },
|
||||
{ STRLEN("restrict"), "restrict" },
|
||||
{ STRLEN("return"), "return" },
|
||||
{ STRLEN("short"), "short" },
|
||||
{ STRLEN("signed"), "signed" },
|
||||
{ STRLEN("sizeof"), "sizeof" },
|
||||
{ STRLEN("static"), "static" },
|
||||
{ STRLEN("static_assert"), "static_assert" },
|
||||
{ STRLEN("struct"), "struct" },
|
||||
{ STRLEN("switch"), "switch" },
|
||||
{ STRLEN("thread_local"), "thread_local" },
|
||||
{ STRLEN("true"), "true" },
|
||||
{ STRLEN("typedef"), "typedef" },
|
||||
{ STRLEN("union"), "union" },
|
||||
{ STRLEN("unsigned"), "unsigned" },
|
||||
{ STRLEN("void"), "void" },
|
||||
{ STRLEN("volatile"), "volatile" },
|
||||
{ STRLEN("while"), "while" },
|
||||
{ STRLEN("xor"), "xor" },
|
||||
{ STRLEN("xor_eq"), "xor_eq" },
|
||||
/**/
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
/*
|
||||
* Keep track of discarded bytes by read_line() so count() can report
|
||||
* correct wc(1) equivalent counts.
|
||||
*/
|
||||
static int xlcount = 0;
|
||||
static int xwcount = 0;
|
||||
static int xbcount = 0;
|
||||
|
||||
static Word *
|
||||
find_member(Word *table, const char *string)
|
||||
{
|
||||
Word *w;
|
||||
for (w = table; w->length != 0; w++) {
|
||||
if (strncmp(string, w->word, w->length) == 0
|
||||
&& !isalnum(string[w->length]) && string[w->length] != '_')
|
||||
return w;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* ISO C11 section 5.2.1.1 Trigraph Sequences, leading sequence "??"
|
||||
*/
|
||||
static char trigraph[] = "=(/)'<!>-";
|
||||
static char asciimap[] = "#[\\]^{|}~";
|
||||
|
||||
static size_t
|
||||
read_line(char *buf, size_t size)
|
||||
{
|
||||
int ch;
|
||||
size_t length;
|
||||
|
||||
if (buf == NULL || size == 0)
|
||||
return 0;
|
||||
|
||||
for (size--, length = 0; length < size; ) {
|
||||
if ((ch = fgetc(stdin)) == EOF)
|
||||
break;
|
||||
/* Map NUL bytes to space, though ideally I should chuck'em. */
|
||||
if (ch == '\0')
|
||||
ch = ' ';
|
||||
/* Discard bare CR and those part of CRLF. */
|
||||
if (ch == '\r') {
|
||||
xbcount++;
|
||||
continue;
|
||||
}
|
||||
/* Trigraph mapping? */
|
||||
if (2 <= length && buf[length-2] == '?' && buf[length-1] == '?') {
|
||||
char *tri;
|
||||
if ((tri = strchr(trigraph, ch)) != NULL) {
|
||||
/* Mapped trigraphs count as 1 byte. */
|
||||
ch = asciimap[tri - trigraph];
|
||||
xbcount += 2;
|
||||
length -= 2;
|
||||
}
|
||||
}
|
||||
if (ch == '\n' && 1 <= length && buf[length-1] == '\\') {
|
||||
/* ISO C11 section 5.1.1.2 Translation Phases
|
||||
* point 2 discards backslash newlines.
|
||||
*/
|
||||
xbcount += 2;
|
||||
xwcount++;
|
||||
xlcount++;
|
||||
length--;
|
||||
continue;
|
||||
}
|
||||
buf[length++] = (char) ch;
|
||||
if (ch == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
buf[length] = '\0';
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/*
|
||||
* Count octets and strip comments. The stripped C input is sent to
|
||||
* standard output. If -s is set, then suppress the source output.
|
||||
* The various counters are sent to standard error.
|
||||
*
|
||||
* The counter output format is:
|
||||
*
|
||||
* lcount wcount bcount icount isaved rcount rsaved
|
||||
*
|
||||
* where
|
||||
* lcount line count (same as wc)
|
||||
* wcount word count (same as wc)
|
||||
* bcount byte count (same as wc)
|
||||
* icount IOCCC secondary size rule count
|
||||
*
|
||||
* No longer reported:
|
||||
* isaved bytes saved by secondary size rule (bcount - icount)
|
||||
* rcount number of C reserved words
|
||||
* rsaved number of octets saved with -r
|
||||
*/
|
||||
static int
|
||||
count(int flags)
|
||||
{
|
||||
Word *w;
|
||||
unsigned long span;
|
||||
char *p, buf[BUFFER_SIZE];
|
||||
int lcount, wcount, bcount;
|
||||
int is_comment, is_word, dquote, escape;
|
||||
int count, keywords, saved, kw_saved;
|
||||
int squote;
|
||||
|
||||
/* Start of buffer sentinel. */
|
||||
buf[0] = ' ';
|
||||
buf[BUFFER_SIZE - 1] = 0; /* paranoia */
|
||||
|
||||
count = saved = 0;
|
||||
keywords = kw_saved = 0;
|
||||
lcount = wcount = bcount = 0;
|
||||
is_comment = is_word = dquote = escape = 0;
|
||||
squote = 0;
|
||||
|
||||
/*
|
||||
* "no matter how well you may think you understand this code,
|
||||
* you don't, so don't mess with it." :-)
|
||||
*/
|
||||
while (0 < read_line(buf+1, sizeof (buf)-1)) {
|
||||
if (!(flags & FLAG_KEEP)) {
|
||||
/* Leading whitespace before comment block? */
|
||||
span = strspn(buf+1, "\t ");
|
||||
|
||||
/* Split / * across reads? */
|
||||
if (buf[1 + span] == '/' && buf[2 + span] == '\0') {
|
||||
(void) ungetc('/', stdin);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* no comment is a comment
|
||||
*/
|
||||
if (buf[1 + span] == '/' && buf[2 + span] == '/') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (buf[1 + span] == '/' && buf[2 + span] == '*') {
|
||||
/* Strip leading whitespace before comment block. */
|
||||
is_comment = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (p = buf+1; *p != '\0'; p++) {
|
||||
/* Within quoted string? */
|
||||
if (dquote) {
|
||||
/* Escape _this_ character. */
|
||||
if (escape) {
|
||||
escape = 0;
|
||||
}
|
||||
|
||||
/* Escape next character. */
|
||||
else if (*p == '\\') {
|
||||
escape = 1;
|
||||
}
|
||||
|
||||
/* Close quoted string? */
|
||||
else if (*p == '"') {
|
||||
dquote = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if (squote) {
|
||||
if (escape)
|
||||
escape = 0;
|
||||
else if (*p == '\\')
|
||||
escape = 1;
|
||||
else if (*p == '\'')
|
||||
squote = 0;
|
||||
}
|
||||
|
||||
/* Not quote string. */
|
||||
else {
|
||||
/* In C comment block? */
|
||||
if (is_comment) {
|
||||
/* Split * / across reads? */
|
||||
if (*p == '*' && p[1] == '\0') {
|
||||
ungetc('*', stdin);
|
||||
break;
|
||||
}
|
||||
|
||||
/* End of comment block? */
|
||||
if (*p == '*' && p[1] == '/') {
|
||||
is_comment = 0;
|
||||
|
||||
if (!(flags & FLAG_KEEP)) {
|
||||
/* Strip whitespace and newline
|
||||
* trailing closing comment.
|
||||
*/
|
||||
p += 1 + strspn(p+2, " \t\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!(flags & FLAG_KEEP)) {
|
||||
/* Strip octets in comment block. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Split / / or / * across reads? */
|
||||
else if (*p == '/' && p[1] == '\0') {
|
||||
ungetc('/', stdin);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Start of comment line? */
|
||||
else if (*p == '/' && p[1] == '/') {
|
||||
if (!(flags & FLAG_KEEP)) {
|
||||
/* Strip comment to end of buffer. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Start of comment block? */
|
||||
else if (*p == '/' && p[1] == '*') {
|
||||
/* Begin comment block. */
|
||||
is_comment = 1;
|
||||
|
||||
if (!(flags & FLAG_KEEP)) {
|
||||
/* Strip comment block. */
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* C reserved word? */
|
||||
else if (!isalnum(p[-1]) && p[-1] != '_'
|
||||
&& (w = find_member(cwords, p)) != NULL) {
|
||||
keywords++;
|
||||
if (flags & FLAG_RESERVED) {
|
||||
bcount += w->length;
|
||||
if (!is_word) {
|
||||
is_word = 1;
|
||||
wcount++;
|
||||
}
|
||||
|
||||
if (!(flags & FLAG_SILENCE)) {
|
||||
fputs(w->word, stdout);
|
||||
}
|
||||
|
||||
/* Count reserved word as one. */
|
||||
kw_saved += w->length - 1;
|
||||
p += w->length - 1;
|
||||
count++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Open single quote string? */
|
||||
else if (*p == '\'') {
|
||||
squote = 1;
|
||||
}
|
||||
|
||||
/* Open quoted string? */
|
||||
else if (*p == '"') {
|
||||
dquote = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(flags & FLAG_SILENCE)) {
|
||||
fputc(*p, stdout);
|
||||
}
|
||||
|
||||
bcount++;
|
||||
if (*p == '\n') {
|
||||
lcount++;
|
||||
}
|
||||
|
||||
/* Ignore all whitespace.
|
||||
*
|
||||
* Well not ALL in the Universe, just all here.
|
||||
*/
|
||||
if (isspace(*p)) {
|
||||
is_word = 0;
|
||||
saved++;
|
||||
continue;
|
||||
} else if (!is_word) {
|
||||
is_word = 1;
|
||||
wcount++;
|
||||
}
|
||||
|
||||
/* Ignore curly braces and semicolons when followed
|
||||
* by any whitespace or EOF.
|
||||
*/
|
||||
if (strchr("{;}", *p) != NULL && (isspace(p[1]) || p[1] == '\0')) {
|
||||
saved++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Count this octet. */
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & FLAG_IOCCC) {
|
||||
/* Output the official IOCCC size tool size to standard out */
|
||||
printf("%d\n", count);
|
||||
if (MAX_SIZE < bcount) {
|
||||
fprintf(stderr, "WARNING: program size (%d) exceeds IOCCC Rule 2a max. size (%d)\n", bcount, MAX_SIZE);
|
||||
}
|
||||
if (MAX_COUNT < count) {
|
||||
fprintf(stderr, "WARNING: iocccsize count (%d) exceeds IOCCC Rule 2b max. count (%d)\n", count, MAX_COUNT);
|
||||
}
|
||||
} else {
|
||||
/* The Ugly Truth */
|
||||
fprintf(
|
||||
stderr, "%d %d %d %d %d %d %d\n",
|
||||
lcount + xlcount, wcount + xwcount, bcount + xbcount, count,
|
||||
saved, keywords, kw_saved
|
||||
);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ch;
|
||||
int flags = 0;
|
||||
|
||||
while ((ch = getopt(argc, argv, "kirsch")) != -1) {
|
||||
switch (ch) {
|
||||
case 'k':
|
||||
flags |= FLAG_KEEP;
|
||||
break;
|
||||
case 'i':
|
||||
flags |= FLAG_IOCCC | FLAG_RESERVED | FLAG_SILENCE;
|
||||
break;
|
||||
case 'r':
|
||||
flags |= FLAG_RESERVED;
|
||||
break;
|
||||
case 's':
|
||||
flags |= FLAG_SILENCE;
|
||||
break;
|
||||
case 'c':
|
||||
flags |= FLAG_SILLY_C;
|
||||
break;
|
||||
case 'h':
|
||||
flags |= FLAG_SILLY_H;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s\n", usage);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
// make test hack: while for do until goto if else switch case default continue return break
|
||||
if (flags == (FLAG_KEEP | FLAG_IOCCC | FLAG_RESERVED | FLAG_SILENCE | FLAG_SILLY_C | FLAG_SILLY_H)) {
|
||||
fprintf(stderr, "The source toasts you a glass to your health!\n"
|
||||
"BTW: judges have toasted a glass of this at the South Pole.\n"
|
||||
"Now try using useful flags.\n\n"
|
||||
"%s\n", usage);
|
||||
return 3;
|
||||
} else if (flags & FLAG_SILLY_C) {
|
||||
fprintf(stderr, "Do you not see this is C?\n\n"
|
||||
"%s\n", usage);
|
||||
return 4;
|
||||
} else if (flags & FLAG_SILLY_H) {
|
||||
fprintf(stderr, "%s\n", usage);
|
||||
return 5;
|
||||
}
|
||||
|
||||
/*
|
||||
* count as directed - 1 Muha .. 2 Muhaha .. 3 Muhahaha ...
|
||||
*/
|
||||
(void) count(flags);
|
||||
|
||||
/*
|
||||
* All Done!!! All Done!!! -- Jessica Noll, age 2
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
function iskeyword {
|
||||
awk 'BEGIN{f="c11";while(getline<f)k[$1]=0}
|
||||
{if($1 in k)k[$1]++}END{for(i in k)print k[i],i}'
|
||||
}
|
||||
cat $* | ./prog -t | iskeyword | sort -k1nr
|
||||
@@ -0,0 +1,436 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
|
||||
<link rel="stylesheet"
|
||||
type="text/css"
|
||||
href="../hint.css">
|
||||
<title>Best abuse of the rules</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Best abuse of the rules</h1>
|
||||
|
||||
<p>Dave Burton<br>
|
||||
<a href="http://ioccc.snox.net">http://ioccc.snox.net</a></p>
|
||||
|
||||
<h2>Judges' comments:</h2>
|
||||
|
||||
<h3>To use:</h3>
|
||||
|
||||
<pre><code>make
|
||||
|
||||
./prog [-tcksri] < file.c
|
||||
</code></pre>
|
||||
|
||||
<h3>Try:</h3>
|
||||
|
||||
<pre><code>./prog -i < prog.c
|
||||
./prog -s < prog.c
|
||||
./prog -sk < prog.c
|
||||
</code></pre>
|
||||
|
||||
<p>If you get stuck, try:</p>
|
||||
|
||||
<pre><code>make test
|
||||
</code></pre>
|
||||
|
||||
<p>If you get really stuck, try:</p>
|
||||
|
||||
<pre><code>man ./tac.man
|
||||
</code></pre>
|
||||
|
||||
<h3>Selected Judges Remarks:</h3>
|
||||
|
||||
<p>They say size isn’t everything, and in the case of IOCCC <a href="http://www.ioccc.org/2018/iocccsize.c">iocccsize.c</a>
|
||||
that is saying something! What is this program weighing and how much does it weigh?</p>
|
||||
|
||||
<h2>Author’s comments:</h2>
|
||||
|
||||
<h2>tac - tokenize and count C and derivative languages</h2>
|
||||
|
||||
<blockquote><pre style="font-style:italic">
|
||||
tac computes C program size
|
||||
(obfuscated / otherwise)
|
||||
by splitting code as tokens small,
|
||||
ignoring space, then counting all.
|
||||
|
||||
It tries quite hard to act the same
|
||||
as counting tool of I-OCCC fame.
|
||||
Some bugs were fixed, it's faster too,
|
||||
and does more things, just add some glue!
|
||||
|
||||
It does far more than print the size:
|
||||
the token part's a better prize!
|
||||
With each upon on a single line,
|
||||
how many things can you design?
|
||||
|
||||
Included is a keyword sorter,
|
||||
de-obfuscator, freq reporter.
|
||||
With code produced as little parts,
|
||||
just add your own creative arts.
|
||||
|
||||
But first you have to figure out
|
||||
the braces part, without a doubt!
|
||||
And then the code - it isn't easy:
|
||||
for as else? That's rather cheesy!
|
||||
|
||||
The rest of it is standard fare:
|
||||
expressions strange, the globals bare,
|
||||
confusing symbols one and oh,
|
||||
and precedence you have to know.
|
||||
|
||||
The keyword list was made external,
|
||||
because of standards change eternal.
|
||||
Thus other languages can now,
|
||||
be counted just like C, somehow!
|
||||
|
||||
I hope you find this code obscure
|
||||
enough to win, and thus procure
|
||||
a public place for all to see
|
||||
how badly I can butcher C!
|
||||
</pre></blockquote>
|
||||
|
||||
|
||||
<h2>Said another way….</h2>
|
||||
|
||||
<p><code>tac</code> is the inverse of <code>cat</code>(1): it un-concatenates its input into C tokens,
|
||||
writing the token stream to stdout. There are options to suppress the token ids,
|
||||
summarize the token counts, and several options to allow it to be compatible
|
||||
with <code>iocccsize</code>.</p>
|
||||
|
||||
<p>The token-based output is quite useful in analyzing source code (see below),
|
||||
and the counter is more accurate than <code>iocccsize</code> (see below); but this can be
|
||||
fixed by using the -c compatibility flag, restoring the following problems as
|
||||
in the official tool:</p>
|
||||
|
||||
<ul>
|
||||
<li>whitespace <strong>within</strong> a string is <strong>not</strong> counted;
|
||||
this seems wrong, as these chars <strong>are</strong> significant</li>
|
||||
<li>“<code>{;}</code>” is not counted within a double-quoted string</li>
|
||||
<li>whitespace preceding a comment is char-counted, unless the comment starts a line</li>
|
||||
<li>-k processes the reserved words within <code>//</code> comments(!), but not <code>/*</code>, changing the counts</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>The following bugs are always corrected:</p>
|
||||
|
||||
<ul>
|
||||
<li>treats <code>/*/</code> as a complete comment (<code>/*/int if for/*/</code> has three keywords)</li>
|
||||
<li>-k enables <code>//*</code> or within a line comment <code>/*</code> to initiate a comment block until following <code>*/</code></li>
|
||||
<li>-k processes double quote characters in <code>//</code> comments -
|
||||
thus a solitary quote consumes everything until the next quote</li>
|
||||
<li>single quotes are not handled correctly (<code>'"'</code> starts a dquote in <code>iocccsize</code>)</li>
|
||||
<li><code>#ifndef</code> is omitted as a keyword (but <code>#ifdef</code> is allowed?)</li>
|
||||
<li>I is not a reserved word.</li>
|
||||
<li><code>tac</code> correctly penetrates <a href="http://ioccc.org/2014/birken/hint.html" title="Best use of port 1701">23rd century cloaking technology</a>. ;-)</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>There is one (known) remaining problem with detection:</p>
|
||||
|
||||
<ul>
|
||||
<li><p>comments between preprocessor hash and keyword are not replaced with whitespace;
|
||||
the following counts #include as two tokens, <code>#</code> and <code>include</code> (not as a reserved word):</p>
|
||||
|
||||
<pre><code> #/*this will not be counted*/include/*correctly*/<stdio.h>
|
||||
</code></pre></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>Fixing this properly hampers backwards compatibility in counting. This requires
|
||||
eliding comments during readsource (ISO 5.1.1.2, phase 3), and yet still
|
||||
counting words correctly absent -k.</p>
|
||||
|
||||
<h2>Backwards Compatibility</h2>
|
||||
|
||||
<p><code>tac</code> was run over all 366 previous IOCCC winning entries:</p>
|
||||
|
||||
<pre><code>find ~/src/obc -type f -name \*.c | wc
|
||||
</code></pre>
|
||||
|
||||
<p>The discrepancies found are documented and explained in the file “discrepancies”.</p>
|
||||
|
||||
<pre><code>find ~/src/obc -type f -a -name "*.c" | xargs ./spotcheck ./prog | ./spotdiff |
|
||||
grep -v keep | diff -bw - discrep* | grep "[<>] cl "
|
||||
</code></pre>
|
||||
|
||||
<p>In summary, there are only 6 unique entries out of 366 that have any variation
|
||||
in Rule 2 counts; in all cases, the differences are due to bugs within
|
||||
<code>iocccsize</code>, described in detail in the file <code>discrepancies</code>. There are only 40
|
||||
files (40/366, ~11%, including originals and variations) that differ at all, 31
|
||||
only in word count; most word count differences appear related to comment block
|
||||
detection, weighted more towards recent entries (2011 and onward = 20/40 ~50%).</p>
|
||||
|
||||
<p>This (minor) variation in word count values has not been addressed since
|
||||
it is not a qualifying metric, nor is it very useful in a programming context:
|
||||
whitespace surrounds English words, not necessarily C tokens, as in <code>a+=1;</code>.</p>
|
||||
|
||||
<p>Accuracy (versus compatibility) is demonstrated through a series of small test cases
|
||||
designed to allow exhaustive, hand-counted values for comparison with the tool values.
|
||||
These test cases were vital in debugging and regression testing, and provided a way to
|
||||
determine which tool was correct when there were differences.</p>
|
||||
|
||||
<blockquote><p>A version of this tool in more clearly written C (tac.c)
|
||||
is presented for the Judge’s consideration as a more accurate replacement for <code>iocccsize</code>.
|
||||
This obfuscated entry is derived from (and compatible with) that code,
|
||||
but due to obfuscation, has had some significant, deep changes for the contest.
|
||||
Nevertheless, the more clearly written code remains a spoiler for this entry.</p></blockquote>
|
||||
|
||||
<p>NB: <code>iocccsize</code> gets a different answer from <code>tac</code> on its own (iocccsize.c) source code;
|
||||
<code>tac</code> gets the correct answer. This is due to the aforementioned bugs within <code>iocccsize</code>,
|
||||
proved by fixing iocccsize.c with the included patch, so <code>iocccsize</code> reports
|
||||
the correct answer for itself.</p>
|
||||
|
||||
<h2>But wait… There’s More!</h2>
|
||||
|
||||
<p>There is no limit on line length, file length, comment length, or identifier length.</p>
|
||||
|
||||
<p><code>tac</code> features an accurate tokenizer; which presents each C token on a line by itself.
|
||||
This feature enables interesting analyses of C (and C++) code, hard to get any other way.</p>
|
||||
|
||||
<p>For instance, here is a simple token counter, useful in finding repeated long tokens, or operator
|
||||
frequency, or counting the references to identifiers, constants, or breadth of use of the
|
||||
language:</p>
|
||||
|
||||
<pre><code>!/bin/sh
|
||||
cat $* | ./prog -t | sort | uniq -c | sort -k1nr
|
||||
</code></pre>
|
||||
|
||||
<p>And here is a C keyword frequency counter:</p>
|
||||
|
||||
<pre><code>#!/bin/sh
|
||||
function iskeyword {
|
||||
awk 'BEGIN{f="c11";while(getline<f)k[$1]=0}
|
||||
{if($1 in k)k[$1]++}END{for(i in k)print k[i],i}'
|
||||
}
|
||||
cat $* | ./prog -t | iskeyword | sort -k1nr
|
||||
</code></pre>
|
||||
|
||||
<p>This script was used to “optimize” the reserved word order so the most frequent IOCCC
|
||||
winning entry keywords are checked first.</p>
|
||||
|
||||
<blockquote><p>An interesting aside: as might be expected, obfuscation has changed the frequency of
|
||||
keyword distribution over time. The top five for the decades:</p>
|
||||
|
||||
<pre><code> 1980s 1990s 2000s 2010s
|
||||
----- ----- ----- -----
|
||||
94 if 532 char 375 if 254 int
|
||||
69 for 524 if 372 char 217 for
|
||||
59 while 417 int 332 int 198 if
|
||||
48 char 223 for 184 for 121 return
|
||||
43 int 223 void 165 return 104 char
|
||||
</code></pre></blockquote>
|
||||
|
||||
<p>The keyword list is external to the program, and is easily changed, sorted, checked, verified.
|
||||
This allows such additional programs in concert with the tool’s primary operation.</p>
|
||||
|
||||
<p>A poor-man’s de-obfuscator can be based upon the output of <code>tac -t</code> and a handful of
|
||||
simple rules (and another use of the external keyword file).
|
||||
A more refined version of this is included in the file <code>unob.sh</code>,
|
||||
but the simple code below is a serviceable obfuscated C de-obfuscator in a <em>scripting language</em>.
|
||||
It really is this easy with <code>tac</code>:</p>
|
||||
|
||||
<pre><code>#!/bin/sh
|
||||
script='
|
||||
BEGIN {
|
||||
last=nl="\n";
|
||||
f="c11"; while(getline <f > 0) kw[$0]++; close(f);
|
||||
}
|
||||
|
||||
function iskw(a) { return a in kw }
|
||||
function indent(a) { return sprintf("%*s", n*3, " ") }
|
||||
function newline() { if (!infor && last != nl) printf last=nl; }
|
||||
function show(a) {
|
||||
if (last==nl) printf "%s", indent()
|
||||
printf "%s%s", space(), a
|
||||
last=a
|
||||
}
|
||||
function space() {
|
||||
return iskw(last) ||
|
||||
(last ~ /[A-Za-z0-9_+-\/%^[&\]\)=:<>;]$/ && $0 !~ /[:;()\[\],]/) ? " " : ""
|
||||
}
|
||||
|
||||
/^\(/ { ++paren }
|
||||
/^\)/ { --paren }
|
||||
|
||||
/^for/ { newline(); infor=1 }
|
||||
infor && /^;/ { ++infor; show($0 " "); next }
|
||||
infor==1 && /^:/ { ++infor }
|
||||
infor>1 && paren==0 { infor=0 }
|
||||
|
||||
/^\?/ { tern++; n++; newline(); show($0 " "); next }
|
||||
tern && /^:/ { newline(); show($0); --tern; --n; next }
|
||||
|
||||
/^#/ { newline(); show($0); newline(); next }
|
||||
/^;/ { show($0); newline(); next }
|
||||
/^{/ { show($0); ++n; newline(); next }
|
||||
/^}/ { n--; newline(); show($0); newline(); next }
|
||||
|
||||
{ show($0) }
|
||||
'
|
||||
cat $* | sed 's/#include/##include/' | cpp -E -trigraphs |
|
||||
sed 's/^# .*$//' | sed 's/^#//' |
|
||||
./prog -t | awk "$script"
|
||||
</code></pre>
|
||||
|
||||
<h2>On the question of obfuscation</h2>
|
||||
|
||||
<ul>
|
||||
<li><p>I assume you noticed the <a href="https://www.youtube.com/watch?v=fUspLVStPbk&start=53" title="Meaning of Life">braces</a>?</p>
|
||||
|
||||
<p><em>Every brace is sacred,<br>
|
||||
Every brace is great.<br>
|
||||
If a brace is wasted,<br>
|
||||
Clang gets quite irate</em>.</p></li>
|
||||
<li><p>Keywords follow the 2010s top five, without the <code>if</code>, for interesting flow control.</p></li>
|
||||
<li>Sometimes a <code>for</code> can be an <code>else</code> - <a href="https://www.youtube.com/watch?v=OHVjs4aobqs" title="Inconceivable">inconceivable</a>!</li>
|
||||
<li>I see the <code>getopt</code>. But “<a href="https://www.youtube.com/watch?v=Ug75diEyiA0" title="Where's the beef?">where’s the beef?</a>”</li>
|
||||
<li><p>No character constants, several int constants, and one string
|
||||
(hint: which does not encode letters) – how does this code parse code?</p>
|
||||
|
||||
<blockquote><p>Interesting aside: how many is “several int constants”?</p>
|
||||
|
||||
<pre><code> ./prog < prog.c 2>/dev/null | awk '$1~/260/{a[$2]++}END{for(i in a)print i,a[i]}'
|
||||
... | wc
|
||||
</code></pre>
|
||||
|
||||
<p>Which numbers are most often used?</p>
|
||||
|
||||
<pre><code> ... | sort -k2nr | sed 5q
|
||||
</code></pre></blockquote></li>
|
||||
<li><p>The code describes its function by careful arrangement of variables up front…</p></li>
|
||||
<li>…coupled with a description of the typical IOCCC contestant, or at least the author</li>
|
||||
<li>Why shouldn’t trigraph parsing be written in trigraph?</li>
|
||||
<li>Where iocccsize.c mocks, this code flaunts:
|
||||
“<em>no matter how well you may think you understand this code, you don’t, so don’t mess with it. :-)</em>”</li>
|
||||
<li><code>O,0,l,1</code> are used to confusing effect, local names obscure global names.</li>
|
||||
<li>Globals are used to pass information between routines: don’t reorder “unrelated” statements….</li>
|
||||
<li>How does the compatibility mode account for the fundamentally different manner of computation?</li>
|
||||
<li>The algorithm is quite efficient; reserved word detection and trigraph parsing particularly so.</li>
|
||||
<li>This may be the first obfuscated submission that provides the means for its own de-obfuscation.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Rule 2</h2>
|
||||
|
||||
<p>The keyword list is externalized as an include file. This presents a useful
|
||||
feature for the source code: not only can the reserved word script above be
|
||||
produced, but the tool can be rebuilt with any set of reserved words, just by
|
||||
using a different list. For instance: removing all the secondary keywords;
|
||||
removing all the C11 keywords; trying just K&R C. Since C++ and Java share the
|
||||
same operators as C, just change the keyword list and <code>tac</code> will correctly
|
||||
tokenize both of these; the tokens >>> and :: can be handled with a short
|
||||
post-filter (tokenfix, included).</p>
|
||||
|
||||
<p>I believe this entry may also satisfy the request for gratuitous use of all the C11 keywords?
|
||||
Whether this context satisfies “intended C language context” is a matter of interpretation. ;-)
|
||||
And <code>tac</code> is ready for the IOCCC++ contest. And the IOJCC trashcan.</p>
|
||||
|
||||
<p>The following reserved word files are included:</p>
|
||||
|
||||
<pre><code>kandr from my venerable 1978 18th printing "The C Programming Language"
|
||||
v7unix 7th edition Unix source code, extracted from c00.c
|
||||
kandr2 from my 1988 1st printing "The C Programming Language", 2e
|
||||
ansi ANS X3.159-1989
|
||||
c99 ISO/IEC 9899:1999(E)
|
||||
c11 ISO/IEC 9899:201x(E) N1570
|
||||
c++98 http://en.cppreference.com/w/cpp/keyword
|
||||
c++11 ISO/IEC 14882:2011(E) N3337 2012-01-16
|
||||
c++14 ISO/IEC 14882:2014(E) N4296 2014-11-09
|
||||
java8 http://docs.oracle.com/javase/specs/index.html
|
||||
ioccc.kw.freq c11 + additional words, sorted on frequency of occurrence in ioccc winners
|
||||
</code></pre>
|
||||
|
||||
<p>NB: The keyword file used in this code is derived from the list in iocccsize.c,
|
||||
which is neither complete (<code>#define</code>, <code>#ifndef</code>, <code>#undef</code> are missing
|
||||
– yes, Virginia knows about <code>#define</code> omitted on purpose),
|
||||
nor correct (many more are added: <code>I</code>, <code>true</code>, <code>bool</code>, <code>compl</code>, …):</p>
|
||||
|
||||
<pre><code>(sed -n '1p' c11; sed -n '2,$p' ioccc.kw.freq | sort) | comm -3 - c11
|
||||
</code></pre>
|
||||
|
||||
<p>That is an obfuscated way to say “diff”. But it also more clearly shows the, um, diffs.</p>
|
||||
|
||||
<p>The usage string is similarly externalized, providing a better usability string than
|
||||
the limits would otherwise allow. If this is considered bending the rules too far,
|
||||
just -DU=O to get a passible, if cryptic, usage message using no additional octets
|
||||
than without the define.
|
||||
This also allows the builder to configure the amount of help a utility should provide
|
||||
(<a href="https://www.youtube.com/watch?v=VU0GYSA1POs" title="Ants">you want a manpage? Because that’s how you get a manpage.</a>)
|
||||
– a rather significant point of contention made moot.</p>
|
||||
|
||||
<p>There is definitely abuse of the Rule2 counter, exploiting a “feature” of <code>iocccsize</code>:
|
||||
<code>iocccsize</code> does not Rule2 count {, } and ; when followed by whitespace – even within a string!
|
||||
Thus: Freecode, a simple, uncounted, highly obfuscated encoding of a central part
|
||||
of this program. (The reserved word list is not Freecoded, both because it is useful
|
||||
apart from the program, and because Freecode is not entirely free.*)</p>
|
||||
|
||||
<ul>
|
||||
<li>Some restrictions apply. Not approved for all uses. Some assembly required.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Compilation</h2>
|
||||
|
||||
<p>The code is ANSI compliant, but it does have a string longer than 509 characters.
|
||||
It has been tested on OSX and Linux, Clang and GCC.</p>
|
||||
|
||||
<p>The code uses trigraphs, ironically: it parses trigraphs with trigraph code.
|
||||
Because that’s funny. And it remains obscure after, so trigraphs are not used for obfuscation.
|
||||
Thus -trigraphs -Wno-trigraphs (which is also humorous).</p>
|
||||
|
||||
<p>It’s obfuscated C. Thus -Wno-parentheses -Wno-empty-body -Wno-char-subscripts.</p>
|
||||
|
||||
<p>The code uses unsigned chars, but C strings are signed. Thus -Wno-pointer-sign.
|
||||
NB: This is <em>not</em> a portability concern, the one string holds only printable ASCII characters.</p>
|
||||
|
||||
<p>Thus:</p>
|
||||
|
||||
<pre><code>clang -ansi -Wall -trigraphs -Wno-trigraphs -Wno-parentheses -Wno-empty-body -Wno-char-subscripts -Wno-pointer-sign -DU=O -DW=\"keywords\" -o prog prog.c
|
||||
</code></pre>
|
||||
|
||||
<h2>Coda</h2>
|
||||
|
||||
<p>Cody Ferguson was relentless in his pursuit of bugs.
|
||||
Thanks to his reports, the version of <code>unob.sh</code> is stronger,
|
||||
<code>tac</code> groks digraphs, <code>tokenfix</code> corrects for missing digraphs in <code>prog.c</code>,
|
||||
and the program <code>manpage</code> was added to the corpus.</p>
|
||||
|
||||
<p><code>manpage</code> is a useful program that turns ASCII versions of man pages (e.g. <code>tac.man</code>) into real
|
||||
man pages. It works for C and C-like languages, command lines,
|
||||
and was designed to handle man page sections 1-8.
|
||||
It works well on most inputs, but tends to need some raw nroff for more fancy constructions,
|
||||
such as combined arguments
|
||||
(e.g. the -r and -s arguments to tac are not recognised when written as -rs in prose).</p>
|
||||
|
||||
<p>Try:</p>
|
||||
|
||||
<pre><code>manpage tac
|
||||
|
||||
manpage -h
|
||||
manpage -h | manpage
|
||||
manpage -h | manpage -R | less
|
||||
manpage -h | manpage -P | lpr
|
||||
</code></pre>
|
||||
|
||||
<hr />
|
||||
|
||||
<!--
|
||||
(c) Copyright 1984-2018, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
|
||||
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
|
||||
|
||||
[judges]: http://www.ioccc.org/judges.html
|
||||
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
-->
|
||||
|
||||
<TABLE><TR>
|
||||
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
|
||||
<TD><P>© Copyright 1984-2018,
|
||||
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
|
||||
- All rights reserved<BR>
|
||||
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
|
||||
<TD> <!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
|
||||
</TR></TABLE>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,397 @@
|
||||
# Best abuse of the rules
|
||||
|
||||
Dave Burton
|
||||
<http://ioccc.snox.net>
|
||||
|
||||
|
||||
## Judges' comments:
|
||||
### To use:
|
||||
|
||||
make
|
||||
|
||||
./prog [-tcksri] < file.c
|
||||
|
||||
### Try:
|
||||
|
||||
./prog -i < prog.c
|
||||
./prog -s < prog.c
|
||||
./prog -sk < prog.c
|
||||
|
||||
If you get stuck, try:
|
||||
|
||||
make test
|
||||
|
||||
If you get really stuck, try:
|
||||
|
||||
man ./tac.man
|
||||
|
||||
### Selected Judges Remarks:
|
||||
|
||||
They say size isn't everything, and in the case of IOCCC [iocccsize.c](http://www.ioccc.org/2018/iocccsize.c)
|
||||
that is saying something! What is this program weighing and how much does it weigh?
|
||||
|
||||
|
||||
## Author's comments:
|
||||
tac - tokenize and count C and derivative languages
|
||||
---------------------------------------------------
|
||||
|
||||
<blockquote><pre style="font-style:italic">
|
||||
tac computes C program size
|
||||
(obfuscated / otherwise)
|
||||
by splitting code as tokens small,
|
||||
ignoring space, then counting all.
|
||||
|
||||
It tries quite hard to act the same
|
||||
as counting tool of I-OCCC fame.
|
||||
Some bugs were fixed, it's faster too,
|
||||
and does more things, just add some glue!
|
||||
|
||||
It does far more than print the size:
|
||||
the token part's a better prize!
|
||||
With each upon on a single line,
|
||||
how many things can you design?
|
||||
|
||||
Included is a keyword sorter,
|
||||
de-obfuscator, freq reporter.
|
||||
With code produced as little parts,
|
||||
just add your own creative arts.
|
||||
|
||||
But first you have to figure out
|
||||
the braces part, without a doubt!
|
||||
And then the code - it isn't easy:
|
||||
for as else? That's rather cheesy!
|
||||
|
||||
The rest of it is standard fare:
|
||||
expressions strange, the globals bare,
|
||||
confusing symbols one and oh,
|
||||
and precedence you have to know.
|
||||
|
||||
The keyword list was made external,
|
||||
because of standards change eternal.
|
||||
Thus other languages can now,
|
||||
be counted just like C, somehow!
|
||||
|
||||
I hope you find this code obscure
|
||||
enough to win, and thus procure
|
||||
a public place for all to see
|
||||
how badly I can butcher C!
|
||||
</pre></blockquote>
|
||||
|
||||
Said another way....
|
||||
--------------------
|
||||
|
||||
`tac` is the inverse of `cat`(1): it un-concatenates its input into C tokens,
|
||||
writing the token stream to stdout. There are options to suppress the token ids,
|
||||
summarize the token counts, and several options to allow it to be compatible
|
||||
with `iocccsize`.
|
||||
|
||||
The token-based output is quite useful in analyzing source code (see below),
|
||||
and the counter is more accurate than `iocccsize` (see below); but this can be
|
||||
fixed by using the -c compatibility flag, restoring the following problems as
|
||||
in the official tool:
|
||||
|
||||
* whitespace **within** a string is **not** counted;
|
||||
this seems wrong, as these chars **are** significant
|
||||
* "`{;}`" is not counted within a double-quoted string
|
||||
* whitespace preceding a comment is char-counted, unless the comment starts a line
|
||||
* -k processes the reserved words within `//` comments(!), but not `/*`, changing the counts
|
||||
|
||||
The following bugs are always corrected:
|
||||
|
||||
* treats `/*/` as a complete comment (`/*/int if for/*/` has three keywords)
|
||||
* -k enables `//*` or within a line comment `/*` to initiate a comment block until following `*/`
|
||||
* -k processes double quote characters in `//` comments -
|
||||
thus a solitary quote consumes everything until the next quote
|
||||
* single quotes are not handled correctly (`'"'` starts a dquote in `iocccsize`)
|
||||
* `#ifndef` is omitted as a keyword (but `#ifdef` is allowed?)
|
||||
* I is not a reserved word.
|
||||
* `tac` correctly penetrates [23rd century cloaking technology][1]. ;-)
|
||||
|
||||
There is one (known) remaining problem with detection:
|
||||
|
||||
* comments between preprocessor hash and keyword are not replaced with whitespace;
|
||||
the following counts #include as two tokens, `#` and `include` (not as a reserved word):
|
||||
|
||||
#/*this will not be counted*/include/*correctly*/<stdio.h>
|
||||
|
||||
Fixing this properly hampers backwards compatibility in counting. This requires
|
||||
eliding comments during readsource (ISO 5.1.1.2, phase 3), and yet still
|
||||
counting words correctly absent -k.
|
||||
|
||||
[1]: http://ioccc.org/2014/birken/hint.html "Best use of port 1701"
|
||||
|
||||
Backwards Compatibility
|
||||
-----------------------
|
||||
|
||||
`tac` was run over all 366 previous IOCCC winning entries:
|
||||
|
||||
find ~/src/obc -type f -name \*.c | wc
|
||||
|
||||
The discrepancies found are documented and explained in the file "discrepancies".
|
||||
|
||||
find ~/src/obc -type f -a -name "*.c" | xargs ./spotcheck ./prog | ./spotdiff |
|
||||
grep -v keep | diff -bw - discrep* | grep "[<>] cl "
|
||||
|
||||
In summary, there are only 6 unique entries out of 366 that have any variation
|
||||
in Rule 2 counts; in all cases, the differences are due to bugs within
|
||||
`iocccsize`, described in detail in the file `discrepancies`. There are only 40
|
||||
files (40/366, ~11%, including originals and variations) that differ at all, 31
|
||||
only in word count; most word count differences appear related to comment block
|
||||
detection, weighted more towards recent entries (2011 and onward = 20/40 ~50%).
|
||||
|
||||
This (minor) variation in word count values has not been addressed since
|
||||
it is not a qualifying metric, nor is it very useful in a programming context:
|
||||
whitespace surrounds English words, not necessarily C tokens, as in `a+=1;`.
|
||||
|
||||
Accuracy (versus compatibility) is demonstrated through a series of small test cases
|
||||
designed to allow exhaustive, hand-counted values for comparison with the tool values.
|
||||
These test cases were vital in debugging and regression testing, and provided a way to
|
||||
determine which tool was correct when there were differences.
|
||||
|
||||
> A version of this tool in more clearly written C (tac.c)
|
||||
> is presented for the Judge's consideration as a more accurate replacement for `iocccsize`.
|
||||
> This obfuscated entry is derived from (and compatible with) that code,
|
||||
> but due to obfuscation, has had some significant, deep changes for the contest.
|
||||
> Nevertheless, the more clearly written code remains a spoiler for this entry.
|
||||
|
||||
NB: `iocccsize` gets a different answer from `tac` on its own (iocccsize.c) source code;
|
||||
`tac` gets the correct answer. This is due to the aforementioned bugs within `iocccsize`,
|
||||
proved by fixing iocccsize.c with the included patch, so `iocccsize` reports
|
||||
the correct answer for itself.
|
||||
|
||||
But wait... There's More!
|
||||
-------------------------
|
||||
|
||||
There is no limit on line length, file length, comment length, or identifier length.
|
||||
|
||||
`tac` features an accurate tokenizer; which presents each C token on a line by itself.
|
||||
This feature enables interesting analyses of C (and C++) code, hard to get any other way.
|
||||
|
||||
For instance, here is a simple token counter, useful in finding repeated long tokens, or operator
|
||||
frequency, or counting the references to identifiers, constants, or breadth of use of the
|
||||
language:
|
||||
|
||||
!/bin/sh
|
||||
cat $* | ./prog -t | sort | uniq -c | sort -k1nr
|
||||
|
||||
And here is a C keyword frequency counter:
|
||||
|
||||
#!/bin/sh
|
||||
function iskeyword {
|
||||
awk 'BEGIN{f="c11";while(getline<f)k[$1]=0}
|
||||
{if($1 in k)k[$1]++}END{for(i in k)print k[i],i}'
|
||||
}
|
||||
cat $* | ./prog -t | iskeyword | sort -k1nr
|
||||
|
||||
This script was used to "optimize" the reserved word order so the most frequent IOCCC
|
||||
winning entry keywords are checked first.
|
||||
|
||||
> An interesting aside: as might be expected, obfuscation has changed the frequency of
|
||||
> keyword distribution over time. The top five for the decades:
|
||||
>
|
||||
> 1980s 1990s 2000s 2010s
|
||||
> ----- ----- ----- -----
|
||||
> 94 if 532 char 375 if 254 int
|
||||
> 69 for 524 if 372 char 217 for
|
||||
> 59 while 417 int 332 int 198 if
|
||||
> 48 char 223 for 184 for 121 return
|
||||
> 43 int 223 void 165 return 104 char
|
||||
|
||||
The keyword list is external to the program, and is easily changed, sorted, checked, verified.
|
||||
This allows such additional programs in concert with the tool's primary operation.
|
||||
|
||||
A poor-man's de-obfuscator can be based upon the output of `tac -t` and a handful of
|
||||
simple rules (and another use of the external keyword file).
|
||||
A more refined version of this is included in the file `unob.sh`,
|
||||
but the simple code below is a serviceable obfuscated C de-obfuscator in a _scripting language_.
|
||||
It really is this easy with `tac`:
|
||||
|
||||
#!/bin/sh
|
||||
script='
|
||||
BEGIN {
|
||||
last=nl="\n";
|
||||
f="c11"; while(getline <f > 0) kw[$0]++; close(f);
|
||||
}
|
||||
|
||||
function iskw(a) { return a in kw }
|
||||
function indent(a) { return sprintf("%*s", n*3, " ") }
|
||||
function newline() { if (!infor && last != nl) printf last=nl; }
|
||||
function show(a) {
|
||||
if (last==nl) printf "%s", indent()
|
||||
printf "%s%s", space(), a
|
||||
last=a
|
||||
}
|
||||
function space() {
|
||||
return iskw(last) ||
|
||||
(last ~ /[A-Za-z0-9_+-\/%^[&\]\)=:<>;]$/ && $0 !~ /[:;()\[\],]/) ? " " : ""
|
||||
}
|
||||
|
||||
/^\(/ { ++paren }
|
||||
/^\)/ { --paren }
|
||||
|
||||
/^for/ { newline(); infor=1 }
|
||||
infor && /^;/ { ++infor; show($0 " "); next }
|
||||
infor==1 && /^:/ { ++infor }
|
||||
infor>1 && paren==0 { infor=0 }
|
||||
|
||||
/^\?/ { tern++; n++; newline(); show($0 " "); next }
|
||||
tern && /^:/ { newline(); show($0); --tern; --n; next }
|
||||
|
||||
/^#/ { newline(); show($0); newline(); next }
|
||||
/^;/ { show($0); newline(); next }
|
||||
/^{/ { show($0); ++n; newline(); next }
|
||||
/^}/ { n--; newline(); show($0); newline(); next }
|
||||
|
||||
{ show($0) }
|
||||
'
|
||||
cat $* | sed 's/#include/##include/' | cpp -E -trigraphs |
|
||||
sed 's/^# .*$//' | sed 's/^#//' |
|
||||
./prog -t | awk "$script"
|
||||
|
||||
On the question of obfuscation
|
||||
------------------------------
|
||||
|
||||
* I assume you noticed the [braces][2]?
|
||||
|
||||
_Every brace is sacred,
|
||||
Every brace is great.
|
||||
If a brace is wasted,
|
||||
Clang gets quite irate_.
|
||||
|
||||
* Keywords follow the 2010s top five, without the `if`, for interesting flow control.
|
||||
* Sometimes a `for` can be an `else` - [inconceivable][3]!
|
||||
* I see the `getopt`. But "[where's the beef?][4]"
|
||||
* No character constants, several int constants, and one string
|
||||
(hint: which does not encode letters) -- how does this code parse code?
|
||||
> Interesting aside: how many is "several int constants"?
|
||||
>
|
||||
> ./prog < prog.c 2>/dev/null | awk '$1~/260/{a[$2]++}END{for(i in a)print i,a[i]}'
|
||||
> ... | wc
|
||||
>
|
||||
> Which numbers are most often used?
|
||||
>
|
||||
> ... | sort -k2nr | sed 5q
|
||||
|
||||
* The code describes its function by careful arrangement of variables up front...
|
||||
* ...coupled with a description of the typical IOCCC contestant, or at least the author
|
||||
* Why shouldn't trigraph parsing be written in trigraph?
|
||||
* Where iocccsize.c mocks, this code flaunts:
|
||||
"_no matter how well you may think you understand this code, you don't, so don't mess with it. :-)_"
|
||||
* `O,0,l,1` are used to confusing effect, local names obscure global names.
|
||||
* Globals are used to pass information between routines: don't reorder "unrelated" statements....
|
||||
* How does the compatibility mode account for the fundamentally different manner of computation?
|
||||
* The algorithm is quite efficient; reserved word detection and trigraph parsing particularly so.
|
||||
* This may be the first obfuscated submission that provides the means for its own de-obfuscation.
|
||||
|
||||
[2]: https://www.youtube.com/watch?v=fUspLVStPbk&start=53 "Meaning of Life"
|
||||
[3]: https://www.youtube.com/watch?v=OHVjs4aobqs "Inconceivable"
|
||||
[4]: https://www.youtube.com/watch?v=Ug75diEyiA0 "Where's the beef?"
|
||||
|
||||
Rule 2
|
||||
------
|
||||
|
||||
The keyword list is externalized as an include file. This presents a useful
|
||||
feature for the source code: not only can the reserved word script above be
|
||||
produced, but the tool can be rebuilt with any set of reserved words, just by
|
||||
using a different list. For instance: removing all the secondary keywords;
|
||||
removing all the C11 keywords; trying just K&R C. Since C++ and Java share the
|
||||
same operators as C, just change the keyword list and `tac` will correctly
|
||||
tokenize both of these; the tokens >>> and :: can be handled with a short
|
||||
post-filter (tokenfix, included).
|
||||
|
||||
I believe this entry may also satisfy the request for gratuitous use of all the C11 keywords?
|
||||
Whether this context satisfies "intended C language context" is a matter of interpretation. ;-)
|
||||
And `tac` is ready for the IOCCC++ contest. And the IOJCC trashcan.
|
||||
|
||||
The following reserved word files are included:
|
||||
|
||||
kandr from my venerable 1978 18th printing "The C Programming Language"
|
||||
v7unix 7th edition Unix source code, extracted from c00.c
|
||||
kandr2 from my 1988 1st printing "The C Programming Language", 2e
|
||||
ansi ANS X3.159-1989
|
||||
c99 ISO/IEC 9899:1999(E)
|
||||
c11 ISO/IEC 9899:201x(E) N1570
|
||||
c++98 http://en.cppreference.com/w/cpp/keyword
|
||||
c++11 ISO/IEC 14882:2011(E) N3337 2012-01-16
|
||||
c++14 ISO/IEC 14882:2014(E) N4296 2014-11-09
|
||||
java8 http://docs.oracle.com/javase/specs/index.html
|
||||
ioccc.kw.freq c11 + additional words, sorted on frequency of occurrence in ioccc winners
|
||||
|
||||
NB: The keyword file used in this code is derived from the list in iocccsize.c,
|
||||
which is neither complete (`#define`, `#ifndef`, `#undef` are missing
|
||||
-- yes, Virginia knows about `#define` omitted on purpose),
|
||||
nor correct (many more are added: `I`, `true`, `bool`, `compl`, ...):
|
||||
|
||||
(sed -n '1p' c11; sed -n '2,$p' ioccc.kw.freq | sort) | comm -3 - c11
|
||||
|
||||
That is an obfuscated way to say "diff". But it also more clearly shows the, um, diffs.
|
||||
|
||||
The usage string is similarly externalized, providing a better usability string than
|
||||
the limits would otherwise allow. If this is considered bending the rules too far,
|
||||
just -DU=O to get a passible, if cryptic, usage message using no additional octets
|
||||
than without the define.
|
||||
This also allows the builder to configure the amount of help a utility should provide
|
||||
([you want a manpage? Because that's how you get a manpage.][5])
|
||||
-- a rather significant point of contention made moot.
|
||||
|
||||
There is definitely abuse of the Rule2 counter, exploiting a "feature" of `iocccsize`:
|
||||
`iocccsize` does not Rule2 count {, } and ; when followed by whitespace -- even within a string!
|
||||
Thus: Freecode, a simple, uncounted, highly obfuscated encoding of a central part
|
||||
of this program. (The reserved word list is not Freecoded, both because it is useful
|
||||
apart from the program, and because Freecode is not entirely free.*)
|
||||
|
||||
* Some restrictions apply. Not approved for all uses. Some assembly required.
|
||||
|
||||
[5]: https://www.youtube.com/watch?v=VU0GYSA1POs "Ants"
|
||||
|
||||
Compilation
|
||||
-----------
|
||||
|
||||
The code is ANSI compliant, but it does have a string longer than 509 characters.
|
||||
It has been tested on OSX and Linux, Clang and GCC.
|
||||
|
||||
The code uses trigraphs, ironically: it parses trigraphs with trigraph code.
|
||||
Because that's funny. And it remains obscure after, so trigraphs are not used for obfuscation.
|
||||
Thus -trigraphs -Wno-trigraphs (which is also humorous).
|
||||
|
||||
It's obfuscated C. Thus -Wno-parentheses -Wno-empty-body -Wno-char-subscripts.
|
||||
|
||||
The code uses unsigned chars, but C strings are signed. Thus -Wno-pointer-sign.
|
||||
NB: This is *not* a portability concern, the one string holds only printable ASCII characters.
|
||||
|
||||
Thus:
|
||||
|
||||
clang -ansi -Wall -trigraphs -Wno-trigraphs -Wno-parentheses -Wno-empty-body -Wno-char-subscripts -Wno-pointer-sign -DU=O -DW=\"keywords\" -o prog prog.c
|
||||
|
||||
Coda
|
||||
----
|
||||
|
||||
Cody Ferguson was relentless in his pursuit of bugs.
|
||||
Thanks to his reports, the version of `unob.sh` is stronger,
|
||||
`tac` groks digraphs, `tokenfix` corrects for missing digraphs in `prog.c`,
|
||||
and the program `manpage` was added to the corpus.
|
||||
|
||||
`manpage` is a useful program that turns ASCII versions of man pages (e.g. `tac.man`) into real
|
||||
man pages. It works for C and C-like languages, command lines,
|
||||
and was designed to handle man page sections 1-8.
|
||||
It works well on most inputs, but tends to need some raw nroff for more fancy constructions,
|
||||
such as combined arguments
|
||||
(e.g. the -r and -s arguments to tac are not recognised when written as -rs in prose).
|
||||
|
||||
Try:
|
||||
|
||||
manpage tac
|
||||
|
||||
manpage -h
|
||||
manpage -h | manpage
|
||||
manpage -h | manpage -R | less
|
||||
manpage -h | manpage -P | lpr
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
<!--
|
||||
(c) Copyright 1984-2018, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
|
||||
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
|
||||
|
||||
[judges]: http://www.ioccc.org/judges.html
|
||||
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
-->
|
||||
@@ -0,0 +1,396 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
int cl,cw,cc,ci,ck,xc; // counts: line, word, char, ioc, keywords, xtra_char
|
||||
int ts,tk; // totals: saved from counting, keyword lengths
|
||||
int fk,fs,fr,fi,fc,ft; // flags: keep, suppress, reserved, ioccc, compat, tokenize, comments
|
||||
unsigned char *buf, *p, *e, *w, *s; // ptr, end, white, start
|
||||
|
||||
char *kw[] = {
|
||||
"void", "char", "short", "int", "long", "unsigned",
|
||||
"typedef", "struct", "union", "enum", "sizeof", "signed",
|
||||
"for", "while", "do", "if", "else", "switch",
|
||||
"case", "default", "break", "continue", "return", "goto",
|
||||
"static", "volatile", "register", "auto", "const", "extern",
|
||||
"float", "double",
|
||||
|
||||
"#ifdef", "#ifndef", "#if", "#else", "#elif", "#endif",
|
||||
"#include", "#error", "#warning", "#line", "#pragma",
|
||||
|
||||
"restrict", "inline", "_Bool", "_Complex", "_Imaginary",
|
||||
|
||||
"_Atomic", "_Generic", "_Noreturn", "_Pragma",
|
||||
"_Static_assert", "_Thread_local", "_Alignas", "_Alignof",
|
||||
"static_assert", "thread_local", "alignas", "alignof", "noreturn",
|
||||
"bool", "true", "false", "compl", "bitand", "bitor",
|
||||
"and", "and_eq", "not", "not_eq",
|
||||
"or", "or_eq", "xor", "xor_eq",
|
||||
0
|
||||
};
|
||||
|
||||
enum {
|
||||
CPP = 256
|
||||
, CMT = 257
|
||||
, KEYW = 258
|
||||
, DIVEQ = 259
|
||||
, MULEQ = 260
|
||||
, MODEQ = 261
|
||||
, ADDEQ = 262
|
||||
, SUBEQ = 263
|
||||
, XOREQ = 264
|
||||
, OREQ = 265
|
||||
, ANDEQ = 266
|
||||
, RSHEQ = 267
|
||||
, LSHEQ = 268
|
||||
, NOTEQ = 269
|
||||
, EQ = 270
|
||||
, GE = 271
|
||||
, LE = 272
|
||||
, OR2 = 273
|
||||
, AND2 = 274
|
||||
, PP = 275
|
||||
, MM = 276
|
||||
, PTR = 277
|
||||
, LSH = 278
|
||||
, RSH = 279
|
||||
, INT = 300
|
||||
, FLOAT = 301
|
||||
, ID = 302
|
||||
};
|
||||
|
||||
enum {
|
||||
O=0x01 // octal
|
||||
, H=0x02 // hex
|
||||
, D=0x04 // decimal
|
||||
, I=0x08 // identifier
|
||||
, W=0x10 // whitespace
|
||||
, B=0x20 // brace, semi
|
||||
, OHD = O|H|D
|
||||
, HD = H|D
|
||||
, HI = H|I
|
||||
};
|
||||
|
||||
char tab[256] = {
|
||||
W, 00, 00, 00, 00, 00, 00, 00, 00, W, W, W, W, W, 00, 00,
|
||||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||||
W, 00, 00, I, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||||
OHD,OHD,OHD,OHD,OHD,OHD,OHD,OHD, HD, HD, 00, B, 00, 00, 00, 00,
|
||||
|
||||
00, HI, HI, HI, HI, HI, HI, I, I, I, I, I, I, I, I, I,
|
||||
I, I, I, I, I, I, I, I, I, I, I, 00, 00, 00, 00, I,
|
||||
00, HI, HI, HI, HI, HI, HI, I, I, I, I, I, I, I, I, I,
|
||||
I, I, I, I, I, I, I, I, I, I, I, B, 00, B, 00, 00,
|
||||
};
|
||||
|
||||
#define is(x, c) (tab[c]&(x))
|
||||
|
||||
// discard backslash-newline as-if not present, even if trigraph backslash
|
||||
// iocccsize counts tri as xbcount+=2, and bs-nl as xb+=2, xw++, xl++ to match wc(1)
|
||||
|
||||
void readsource() {
|
||||
int c, o=2, len=128;
|
||||
buf = malloc(len);
|
||||
while ((c = getchar()) != EOF) {
|
||||
if (c == '\r') {
|
||||
if (fc) ++xc;
|
||||
continue;
|
||||
}
|
||||
if (buf[o-1] == '?' && buf[o-2] == '?') {
|
||||
char *tri = "=#([/\\)]'^<{!|>}-~";
|
||||
while (*tri && *tri++ != c)
|
||||
++tri;
|
||||
if (*tri) {
|
||||
c = *tri;
|
||||
o -= 2;
|
||||
if (fc) xc += 2;
|
||||
}
|
||||
}
|
||||
if (c == '\n' && buf[o-1] == '\\') {
|
||||
--o;
|
||||
cl++;
|
||||
if (fc) {
|
||||
++cw;
|
||||
xc += 2;
|
||||
}
|
||||
} else
|
||||
buf[o++] = c;
|
||||
if (o == len)
|
||||
buf = realloc(buf, len+=128);
|
||||
}
|
||||
buf[o] = 0;
|
||||
e = buf + o;
|
||||
p = buf += 2;
|
||||
}
|
||||
|
||||
int iskw(char *s, int len) {
|
||||
char **k;
|
||||
if (len > 1)
|
||||
for (k = kw; *k; ++k)
|
||||
if (s[0] == k[0][0] && k[0][len] == 0 && strncmp(s, *k, len) == 0)
|
||||
return ++ck, (tk+=len-1), 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int want(char m) {
|
||||
while (p < e) {
|
||||
if (*p == '\\') {
|
||||
// need to only ignore: ntbrfva?, octal, x, hex
|
||||
// 0111 = two chars, \091 = three chars, \xabc = one char(!)
|
||||
// for our purposes, only worry about: and \ newline,
|
||||
// which is not a newline, but an embedded line break
|
||||
if (p[1] == '\\' || p[1] == '\'' || p[1] == '"' || p[1] == '\n') {
|
||||
if (p[1] == '\n') ++cl;
|
||||
p += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (*p == '\n') ++cl;
|
||||
if (*p++ == m) return m;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int follow(char m, int y, int n) {
|
||||
if (*p == m) return ++p,y;
|
||||
return n;
|
||||
}
|
||||
|
||||
int follow2(char m, int y, int n, int y2) {
|
||||
if (*p == m) return ++p,y;
|
||||
if (*p == n) return ++p,y2;
|
||||
return n;
|
||||
}
|
||||
|
||||
int skipwhite() {
|
||||
int c;
|
||||
for (c=*p++; p<=e && is(W, c); c=*p++) {
|
||||
++cc;
|
||||
if (c == '\n') ++cl;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
* CPP tokens may extend beyond a single line of text and include comments
|
||||
* To do this correctly, need to scan and remove comments during readsource
|
||||
* and present comments as whitespace. Note that "# include" is a valid CPP
|
||||
* token, and does not match "#include".
|
||||
*
|
||||
* Because the global pointers p, s and w are well-known, and because comments
|
||||
* are not consumed during readsource, it is more difficult to parse CPP stuff.
|
||||
* Also note that for backwards compat, we need to also count words correctly,
|
||||
* with and without -k.
|
||||
*/
|
||||
|
||||
int lex() {
|
||||
int c, t;
|
||||
|
||||
w = p;
|
||||
c = skipwhite();
|
||||
s = p-1;
|
||||
|
||||
if (p >= e)
|
||||
return c;
|
||||
|
||||
switch (c) {
|
||||
case '\'': want(c); return c;
|
||||
case '"': want(c); return c;
|
||||
case '/':
|
||||
t = follow2('=', DIVEQ, c, CMT);
|
||||
if (t == CMT)
|
||||
want('\n');
|
||||
else if (t == c && (t = follow('*', CMT, c)) == CMT)
|
||||
do want('*'); while (p<e && follow('/', 0, 1));
|
||||
return t;
|
||||
case '*': return follow ('=', MULEQ, c);
|
||||
case '%': return follow ('=', MODEQ, c);
|
||||
case '=': return follow ('=', EQ, c);
|
||||
case '!': return follow ('=', NOTEQ, c);
|
||||
case '^': return follow ('=', XOREQ, c);
|
||||
case '+': return follow2('=', ANDEQ, c, PP);
|
||||
case '|': return follow2('=', OREQ, c, OR2);
|
||||
case '&': return follow2('=', ANDEQ, c, AND2);
|
||||
case '-': t = follow2('=', SUBEQ, c, MM); return t==c ?follow('>', PTR, t):t;
|
||||
case '>': t = follow2('=', GE, c, RSH); return t==RSH?follow('=', RSHEQ, t):t;
|
||||
case '<': t = follow2('=', LE, c, LSH); return t==LSH?follow('=', LSHEQ, t):t;
|
||||
case '#': if (ft) { want('\n'); return CPP; }
|
||||
}
|
||||
|
||||
if (is(D, c)) {
|
||||
if (c == '0' && (*p|32) == 'x')
|
||||
c = *++p;
|
||||
while (is(OHD, c))
|
||||
c = *p++;
|
||||
if (c == '.') {
|
||||
(void)strtod(s, (char**)&p);
|
||||
return FLOAT;
|
||||
}
|
||||
return --p, INT;
|
||||
}
|
||||
|
||||
if (is(I, c)) {
|
||||
while (is(I|D, c))
|
||||
c = *p++;
|
||||
--p;
|
||||
return iskw(s, p-s) ? KEYW : ID;
|
||||
}
|
||||
|
||||
return c ? c : ' '; // allows nulls in source code
|
||||
}
|
||||
|
||||
// iocccsize compat: adjust whitespace counts
|
||||
void compat_words(int tlen, int inword) {
|
||||
int c;
|
||||
for (c=0; c<tlen; ++c) {
|
||||
int isw = is(W,s[c]);
|
||||
if (isw) --ci;
|
||||
else if (is(B,s[c]) && is(W,s[c+1])) --ci;
|
||||
if (inword) inword = !isw;
|
||||
else if (!isw) inword = ++cw;
|
||||
}
|
||||
}
|
||||
|
||||
void compat_kw(int tlen, int inword) {
|
||||
int c, w=0;
|
||||
for (w=c=2; c<tlen; ++c) { // skip comment lead-in chars
|
||||
int isw = !is(I|D,s[c]);
|
||||
if (inword) {
|
||||
inword = !isw;
|
||||
if (!inword && iskw(s+w, c-w))
|
||||
ci -= c-w-1;
|
||||
} else if (!isw)
|
||||
inword = w = c;
|
||||
}
|
||||
}
|
||||
|
||||
void compat(int t, int tlen) {
|
||||
static int tprev;
|
||||
int c;
|
||||
if (tprev == CMT) {
|
||||
// do not bcount spaces following comment blocks, including the newline!
|
||||
// nor lcount the newline following a comment block if last on line
|
||||
unsigned char *ow = w;
|
||||
while (ow<s && *ow++ != '\n')
|
||||
;
|
||||
if (!fk && ow[-1] == '\n')
|
||||
--cl;
|
||||
cc -= ow-w;
|
||||
tprev = 0;
|
||||
}
|
||||
// new-style comments eat preceding newline, leaving no whitespace if token starts line
|
||||
// add it back here for compat word boundary detection
|
||||
if (w == s && w[-1] == '\n')
|
||||
--w;
|
||||
if (t == CMT) {
|
||||
// do not count newlines within comments
|
||||
// and checks for keywords in new-style comments
|
||||
if (fk) {
|
||||
int inword = w==s && s>buf;
|
||||
ci += tlen;
|
||||
if (s[1] == '/')
|
||||
compat_kw(tlen, inword);
|
||||
compat_words(tlen, inword);
|
||||
} else for (c=0; c<tlen; ++c)
|
||||
if (s[c] == '\n') --cl;
|
||||
|
||||
// nor spaces before comments IFF the comment is first non-white on line
|
||||
unsigned char *os = s;
|
||||
while (os > w) {
|
||||
if (*--os == '\n')
|
||||
break;
|
||||
}
|
||||
|
||||
// look for last ends with newline, only remove ccounts if whitespace
|
||||
if (*os == '\n' || os == buf || w[-1] == '\n')
|
||||
cc -= s - os - (*os == '\n');
|
||||
|
||||
// look for whitespace before the comment, as well as after
|
||||
if (!fk && (w != s || s == buf) && !is(W, s[tlen]) && s[1] == '*')
|
||||
++cw;
|
||||
|
||||
if (s[1] == '*')
|
||||
tprev = CMT;
|
||||
} else if (t == '"' || t == '\'') {
|
||||
// iocccsize -i does not count whitespace WITHIN a string!!!
|
||||
// and {;} can be "free" within a string if follows the "rules"
|
||||
compat_words(tlen, 1);
|
||||
}
|
||||
// count words, not tokens (a preceding old-style CMT is whitespace)
|
||||
if (t && t != CMT && w == s && s > buf)
|
||||
--cw;
|
||||
if (!fs && (t != CMT || fk)) {
|
||||
printf("%.*s", (int)(s-w), w);
|
||||
printf("%.*s", tlen, s);
|
||||
}
|
||||
}
|
||||
|
||||
void count() {
|
||||
int t, tlen;
|
||||
while ((t=lex())) {
|
||||
tlen = p-s;
|
||||
if (t != CMT) {
|
||||
cc += tlen;
|
||||
++cw;
|
||||
if (fr && t == KEYW)
|
||||
ci += 1;
|
||||
else if (t < 256 && is(B, t) && (is(W, *p) || !*p))
|
||||
;
|
||||
else
|
||||
ci += tlen;
|
||||
}
|
||||
if (fc)
|
||||
compat(t, tlen);
|
||||
else if (!fs && (t != CMT || fk)) {
|
||||
if (!ft) printf("%3d ", t);
|
||||
printf("%.*s", tlen, s);
|
||||
if (p[-1] != '\n') printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (fc) {
|
||||
compat(0, e-w);
|
||||
if (!fs && w<e)
|
||||
printf("%.*s", (int)(e-w), w);
|
||||
}
|
||||
|
||||
if (fk) cc = e - buf;
|
||||
if (!fr) tk = 0;
|
||||
ts = cc - ci - tk;
|
||||
cc += xc;
|
||||
}
|
||||
|
||||
int main(int ac, char **av) {
|
||||
static char usage[] = "[flags]\n\
|
||||
-t tokenize input\n\
|
||||
-c compatible with iocccsize\n\
|
||||
-k keep comments\n\
|
||||
-s suppress source\n\
|
||||
-r reserved words count as 1\n\
|
||||
-i ioccc size (implies -rsc)";
|
||||
|
||||
int c;
|
||||
while ((c = getopt(ac, av, "?tcksri")) != EOF) {
|
||||
switch (c) {
|
||||
case 't': ft=1; break;
|
||||
case 'c': fc=1; break;
|
||||
case 'k': fk=1; break;
|
||||
case 's': fs=1; break;
|
||||
case 'r': fr=1; break;
|
||||
case 'i': fi=fr=fs=fc=1; break;
|
||||
default:
|
||||
fprintf(stderr, "%s %s\n", av[0], usage);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
readsource();
|
||||
count();
|
||||
|
||||
if (!ft) {
|
||||
if (fi) printf("%d\n", ci);
|
||||
else fprintf(stderr, "%d %d %d %d %d %d %d\n", cl, cw, cc, ci, ts, ck, tk);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
$ derived from iocccsize.c, which has many additions, and three cpp ommisions $
|
||||
if
|
||||
int
|
||||
for
|
||||
return
|
||||
void
|
||||
char
|
||||
while
|
||||
typedef
|
||||
else
|
||||
goto
|
||||
do
|
||||
#include
|
||||
case
|
||||
sizeof
|
||||
struct
|
||||
long
|
||||
unsigned
|
||||
break
|
||||
const
|
||||
double
|
||||
float
|
||||
short
|
||||
union
|
||||
switch
|
||||
default
|
||||
continue
|
||||
static
|
||||
volatile
|
||||
enum
|
||||
auto
|
||||
extern
|
||||
register
|
||||
signed
|
||||
#ifdef
|
||||
#else
|
||||
#endif
|
||||
inline
|
||||
restrict
|
||||
#ifndef
|
||||
#if
|
||||
#elif
|
||||
#error
|
||||
#warning
|
||||
#line
|
||||
#pragma
|
||||
_Bool
|
||||
_Complex
|
||||
_Imaginary
|
||||
_Atomic
|
||||
_Generic
|
||||
_Noreturn
|
||||
_Pragma
|
||||
_Static_assert
|
||||
_Thread_local
|
||||
_Alignas
|
||||
_Alignof
|
||||
static_assert
|
||||
thread_local
|
||||
alignas
|
||||
alignof
|
||||
noreturn
|
||||
bool
|
||||
true
|
||||
false
|
||||
compl
|
||||
bitand
|
||||
bitor
|
||||
and
|
||||
and_eq
|
||||
not
|
||||
not_eq
|
||||
or
|
||||
or_eq
|
||||
xor
|
||||
xor_eq
|
||||
@@ -0,0 +1,4 @@
|
||||
/*/int if while -- how many keywords?/*/
|
||||
main() {
|
||||
printf("howdy!\n");
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// bug shows under -k
|
||||
//* int if while
|
||||
main(int ac, char **av) {
|
||||
if (ac > 1)
|
||||
while(--ac) puts(*++av);
|
||||
else
|
||||
puts("none");
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/* word count incorrect except with -k; view output with no args */
|
||||
main(){
|
||||
printf(/*testing*/
|
||||
"hello, world\n");
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// this shows the impact of " quotes with -k
|
||||
char*dquote="dquote";
|
||||
main(int ac, char **av) {
|
||||
if (ac > 1 && av[1][0] == '\"')
|
||||
printf(dquote);
|
||||
if (ac == 0)
|
||||
printf("int ac is zero\n");
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// I is an identifier, not a reserved word
|
||||
enum Foo {
|
||||
I = 1,
|
||||
O = 2
|
||||
};
|
||||
main(int ac, char**av) {
|
||||
for(--ac; *++av; )
|
||||
switch (*av[0]-'0') {
|
||||
case I: puts("input"); break;
|
||||
case O: puts("output"); break;
|
||||
default: puts("whatever"); break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include<stdio.h>
|
||||
#undef FOO
|
||||
#ifndef FOO
|
||||
int main() {
|
||||
printf("howdy!\n");
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
$ http://docs.oracle.com/javase/specs/index.html, Java SE 8 $
|
||||
abstract
|
||||
assert
|
||||
boolean
|
||||
break
|
||||
byte
|
||||
case
|
||||
catch
|
||||
char
|
||||
class
|
||||
const
|
||||
continue
|
||||
default
|
||||
do
|
||||
double
|
||||
else
|
||||
enum
|
||||
extends
|
||||
final
|
||||
finally
|
||||
float
|
||||
for
|
||||
if
|
||||
goto
|
||||
implements
|
||||
import
|
||||
instanceof
|
||||
int
|
||||
interface
|
||||
long
|
||||
native
|
||||
new
|
||||
package
|
||||
private
|
||||
protected
|
||||
public
|
||||
return
|
||||
short
|
||||
static
|
||||
strictfp
|
||||
super
|
||||
switch
|
||||
synchronized
|
||||
this
|
||||
throw
|
||||
throws
|
||||
transient
|
||||
try
|
||||
void
|
||||
volatile
|
||||
while
|
||||
true
|
||||
false
|
||||
null
|
||||
@@ -0,0 +1,38 @@
|
||||
$ Kernighan & Ritchie, (1978) _The C Programming Language_, 180,207-208 $
|
||||
#define
|
||||
#else
|
||||
#endif
|
||||
#if
|
||||
#ifdef
|
||||
#ifndef
|
||||
#include
|
||||
#line
|
||||
#undef
|
||||
auto
|
||||
break
|
||||
case
|
||||
char
|
||||
continue
|
||||
default
|
||||
do
|
||||
double
|
||||
else
|
||||
entry
|
||||
extern
|
||||
float
|
||||
for
|
||||
goto
|
||||
if
|
||||
int
|
||||
long
|
||||
register
|
||||
return
|
||||
short
|
||||
sizeof
|
||||
static
|
||||
struct
|
||||
switch
|
||||
typedef
|
||||
union
|
||||
unsigned
|
||||
while
|
||||
@@ -0,0 +1,48 @@
|
||||
$ Kernighan & Ritchie, (1988) _The C Programming Manual, Second Edition_, 192,230-233 $
|
||||
#define
|
||||
#elif
|
||||
#else
|
||||
#endif
|
||||
#error
|
||||
#if
|
||||
#ifdef
|
||||
#ifndef
|
||||
#include
|
||||
#line
|
||||
#pragma
|
||||
#undef
|
||||
asm
|
||||
auto
|
||||
break
|
||||
case
|
||||
char
|
||||
const
|
||||
continue
|
||||
default
|
||||
defined
|
||||
do
|
||||
double
|
||||
else
|
||||
enum
|
||||
extern
|
||||
float
|
||||
for
|
||||
fortran
|
||||
goto
|
||||
if
|
||||
int
|
||||
long
|
||||
register
|
||||
return
|
||||
short
|
||||
signed
|
||||
sizeof
|
||||
static
|
||||
struct
|
||||
switch
|
||||
typedef
|
||||
union
|
||||
unsigned
|
||||
void
|
||||
volatile
|
||||
while
|
||||
@@ -0,0 +1,484 @@
|
||||
#!/bin/sh
|
||||
|
||||
function usage {
|
||||
cat <<'EoT'
|
||||
NAME
|
||||
manpage - format an ascii text file into man page format
|
||||
|
||||
SYNOPSIS
|
||||
manpage [-PR] [-d pdate] [-r rel] [-v vol] [-s sect] [-t title]
|
||||
[-w ncols] [filename]
|
||||
|
||||
DESCRIPTION
|
||||
manpage converts its input into the man(7) macros as used by man(1),
|
||||
but without the user needed to understand any formatting syntax.
|
||||
It is designed to process a flat ascii file that roughly appears in the format
|
||||
desired, adding the specific flourishes that distinguish a readable man page:
|
||||
|
||||
- font changes for names and arguments throughout the document
|
||||
- automatic recognition of command, C, C++, and Java names, types and arguments
|
||||
- automatic recognition of paragraphs, list formats, sections, and non-formatted displays
|
||||
- constant width fonts for code and displays
|
||||
- cross-references highlighted
|
||||
- pass-through of nroff formatting commands
|
||||
|
||||
The input resembles the man page to be formatted, with just a few rules of presentation:
|
||||
Sections ~
|
||||
Section names are input lines in all upper case. If a section name begins
|
||||
with spaces, it starts a subsection.
|
||||
Paragraphs ~
|
||||
A blank line between text marks a paragraph. All text in the same
|
||||
paragraph must be left-aligned relative to itself.
|
||||
Line Breaks ~
|
||||
A twiddle (~) at the end of a line is consumed and replaced
|
||||
with a line break. This is especially useful in tag lists (this section).
|
||||
Displays ~
|
||||
These are sections not to be formatted further. They are introduced
|
||||
by a preceding blank line and indented relative to the surrounding text.
|
||||
Displays are output in constant width font, and all code escapes may
|
||||
be presented naturally:
|
||||
|
||||
printf("Hello, World\n");
|
||||
|
||||
Tag Lists ~
|
||||
The tag is identified by three (3) or more spaces between itself
|
||||
and its description. These rules are tag lists. Note especially
|
||||
the trailing spaces on the tags in this section.
|
||||
Bullet Lists ~
|
||||
These are identified by a leading dash (-), dot (.), or star (*).
|
||||
Numbered Lists ~
|
||||
These begin with a number and a dot; e.g. "3. Number three".
|
||||
Cross References ~
|
||||
This is a word followed by a number in parenthesis; e.g. man(1).
|
||||
Bold / Italic ~
|
||||
A word surrounded by underscores (_) is rendered in _italic_;
|
||||
and by stars (*) is rendered as *boldface*.
|
||||
|
||||
There are two sections handled specially:
|
||||
NAME
|
||||
This is the name of the command or function, followed by a terse,
|
||||
one-line summary of its primary use.
|
||||
SYNOPSIS
|
||||
This section is scanned for names, arguments, and flags. Names found
|
||||
in this area are remembered, and each occurance throughout the document
|
||||
are presented in bold. Arguments are similarly detected and remembered,
|
||||
and presented in italics. Other text in this area is presented in
|
||||
a constant width font.
|
||||
|
||||
OPTIONS
|
||||
-d pdate set the man page date
|
||||
-r rel set the release name
|
||||
-v vol set the volume name
|
||||
-s sect set the section name
|
||||
-t title set the man page title
|
||||
-w ncols force the output to be ncols wide
|
||||
-P PostScript output
|
||||
-R roff output
|
||||
|
||||
EXAMPLES
|
||||
This usage is in the proper format for manpage. Try:
|
||||
|
||||
manpage -h | manpage -tmanpage -s1
|
||||
|
||||
To view the nroff(1) formatted page, perhaps for inclusion in the system man pages:
|
||||
|
||||
manpage -h | manpage -tmanpage -s1 -R > manpage.1
|
||||
|
||||
ENVIRONMENT
|
||||
PAGER defaults to less(1); used if neither -P nor -R is specified as arguments
|
||||
MANPATH input .man files searched in current dir, then HOME/man, then MANPATH
|
||||
ORG name of organization (e.g. $ORG Reference Manual)
|
||||
|
||||
SEE ALSO
|
||||
man(1), man(7), groff(1), less(1), txt2man(1)
|
||||
|
||||
PORTABILITY
|
||||
This program uses generic bourne shell and awk syntax, POSIX compatible systems should work.
|
||||
|
||||
BUGS
|
||||
Code displays that span page breaks do not restore the troff(1) escape
|
||||
during header / footer processing.
|
||||
|
||||
AUTHOR
|
||||
Dave Burton <ioccc@snox.net>
|
||||
|
||||
manpage(1) input format is inspired by txt2man(1) by Marc Vertes <mvertes@free.fr>,
|
||||
although the code is a clean redesign from first principles.
|
||||
EoT
|
||||
}
|
||||
|
||||
function getwidth {
|
||||
echo $(stty -a 2>/dev/null) |
|
||||
if test $(uname) == "Darwin"; then
|
||||
awk '/columns/{for(i=1;i<=NF;++i)if($i~/columns/)print$(i-1)+0}'
|
||||
else
|
||||
awk '/columns/{for(i=1;i<=NF;++i)if($i~/columns/)print$(i+1)+0}'
|
||||
fi
|
||||
}
|
||||
|
||||
function scan {
|
||||
for dir in . $HOME/man $(echo $MANPATH | tr : '\n'); do
|
||||
test -r $dir/$1 && { echo $dir/$1; break; }
|
||||
done
|
||||
}
|
||||
|
||||
function searchfor {
|
||||
# examine the current dir for name, name.man, or scan a searchpath for name.man
|
||||
test "$1" || { echo ""; return; }
|
||||
filename=$1
|
||||
if ! test -r $filename || test -x $filename; then
|
||||
expr "$filename" : .*.man >/dev/null 2>&1 || filename=$filename.man
|
||||
result=$(scan $filename)
|
||||
if ! test "$result"; then
|
||||
echo cannot find $filename in curdir, $HOME/man or MANPATH >&2
|
||||
exit 1
|
||||
fi
|
||||
filename=$result
|
||||
fi
|
||||
echo $filename
|
||||
}
|
||||
|
||||
width=0
|
||||
sys=($uname -s)
|
||||
date= rel= vol= sect= title=
|
||||
post=
|
||||
|
||||
args="?hPRd:r:v:s:t:w:"
|
||||
while getopts $args opt
|
||||
do
|
||||
case $opt in
|
||||
d) date=$OPTARG;;
|
||||
r) rel=$OPTARG;;
|
||||
v) vol=$OPTARG;;
|
||||
s) sect=$OPTARG;;
|
||||
t) title=$OPTARG;;
|
||||
w) width=$OPTARG;;
|
||||
P) post="groff -man -Tps";;
|
||||
R) post=cat;;
|
||||
\?) echo "usage: $0 [-$args] [filename]" >&2; exit 1;;
|
||||
h|*) usage; exit 1;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
date=${date:-$(date +'%d %B %Y')}
|
||||
|
||||
# format and display the page now
|
||||
if test $width -eq 0 -a ! "$post" ; then
|
||||
width=$(getwidth)
|
||||
fi
|
||||
|
||||
# -is for pre-el-capitan
|
||||
: ${post:="groff -man -Tascii | ${PAGER:-less -R}"}
|
||||
|
||||
# seek for it, perhaps without the .man extension
|
||||
filename=$(searchfor $1) || exit; shift;
|
||||
# echo $filename; exit
|
||||
|
||||
# intuit the title, section and volume from the input file
|
||||
if ! test "$title" && test "$filename"; then
|
||||
title=${filename##*/}; title=${title%.man}
|
||||
title=$(echo $title | tr a-z A-Z)
|
||||
if sed '/DESCRIPTION/q' $filename | egrep -q "#include|.import"; then
|
||||
sect=${sect:-3}
|
||||
vol=${vol:-"$ORG Programmer's Manual"}
|
||||
else
|
||||
sect=${sect:-1}
|
||||
vol=${vol:-"$ORG Reference Manual"}
|
||||
fi
|
||||
fi
|
||||
|
||||
# --------------------------------------------------
|
||||
# the formatting engine
|
||||
|
||||
expand $filename |
|
||||
awk -v width=$width -v th="$title $sect \"$date\" \"$rel\" \"$vol\"" '
|
||||
BEGIN {
|
||||
if (width+0 > 0) {
|
||||
# adjust output to a specific width; useful as man(1) replacement
|
||||
cpi = (width+0)/11
|
||||
print ".ll " cpi "i"
|
||||
print ".nr LL " cpi "i"
|
||||
}
|
||||
print ".TH", th
|
||||
print ".if n .na\n.if n .nh"
|
||||
block = 0 # depth of the block display
|
||||
list = 0 # depth of the list indent
|
||||
indent = 0 # current RS indent level
|
||||
rs[indent] = 0 # array of starting indents
|
||||
lw = 0 # leading whitespace
|
||||
blank = 0 # NR of last blank line
|
||||
}
|
||||
|
||||
function bold(w) { return "\\fB" w "\\fP" }
|
||||
function italic(w) { return "\\fI" w "\\fP" }
|
||||
|
||||
function before(s) { return substr(s, 1, RSTART-1) }
|
||||
function after(s) { return substr(s, RSTART+RLENGTH) }
|
||||
|
||||
function add(t, r) {
|
||||
gsub(/\./, "\\.", t)
|
||||
pattern[t] = r
|
||||
}
|
||||
|
||||
# replace logic is W*P, but both W (words) and P (patterns) are small,
|
||||
# and this is the only way to portably, reliably detect substitutable patterns
|
||||
# within the larger text
|
||||
#
|
||||
function replace(dummy, i,count,other,pat,re) {
|
||||
other = "[^-_A-Za-z0-9]+"
|
||||
for (i=1; i<=NF; ++i) {
|
||||
count = 0
|
||||
for (pat in pattern) {
|
||||
# re = "^" pat "$|^" other pat "$|^" pat other "$|^" other pat other "$"
|
||||
re = "^" pat "$|" other pat "$|^" pat other "|" other pat other
|
||||
if ($i ~ re) {
|
||||
count = sub(pat, pattern[pat], $i)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
# one-time, in place bold, italic, and cross-ref
|
||||
if (section != "SYNOPSIS" && count == 0) {
|
||||
# match foo(1) or foo(1pkg) not foo(1 2) or foo(1, 2) or foo(int)
|
||||
# but not in a see also section
|
||||
if ((section != "SEE") && # aka SEE ALSO
|
||||
($i ~ /[_A-Za-z0-9]+\([0-9][A-Za-z0-9]*\)/)) {
|
||||
a = index($i, "(")
|
||||
$i = bold(substr($i, 1, a-1)) substr($i, a)
|
||||
}
|
||||
else if (match($i, "[A-Za-z]_.*_[A-Za-z]"))
|
||||
;
|
||||
else if (match($i, "_.*_"))
|
||||
$i = before($i) italic(substr($i, RSTART+1, RLENGTH-2)) after($i)
|
||||
else if (match($i, "\\*.*\\*"))
|
||||
$i = before($i) bold(substr($i, RSTART+1, RLENGTH-2)) after($i)
|
||||
}
|
||||
}
|
||||
if ($NF == "~") {
|
||||
$NF = ""
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
function paragraph() {
|
||||
print ".PP"
|
||||
list = lw # reset list on a paragraph
|
||||
tplen = ""
|
||||
}
|
||||
|
||||
function restore() {
|
||||
if (blank == NR-1) # restore the blank line to the display
|
||||
print ""
|
||||
n = lw - block
|
||||
if (n==0) n=1 # avoid eating leading dots in displays
|
||||
printf "%*s", n, " " # restore leading spaces in displays
|
||||
}
|
||||
|
||||
function block_start() {
|
||||
block = lw
|
||||
blank = 0
|
||||
paragraph()
|
||||
print ".RS " block
|
||||
print ".eo\n.nf\n.fam C"
|
||||
}
|
||||
|
||||
function block_end() {
|
||||
if (block > 0) {
|
||||
block = 0
|
||||
print ".ec\n.fi\n.fam T"
|
||||
print ".RE"
|
||||
}
|
||||
}
|
||||
|
||||
function reset_indent() {
|
||||
rs[0] = indent = 0
|
||||
}
|
||||
|
||||
# pass through nroff formatting commands
|
||||
/^\..+/ {
|
||||
print $0
|
||||
next
|
||||
}
|
||||
|
||||
# remember leading whitespace, strip blank lines
|
||||
{
|
||||
lw = match($0, /[^ ]/)
|
||||
if (lw == 0) {
|
||||
blank = NR
|
||||
next
|
||||
} else {
|
||||
$0 = substr($0, lw)
|
||||
# sub(/^ */, "")
|
||||
# sub(/ *$/, "") # prevents TP match if desc on next line
|
||||
}
|
||||
--lw
|
||||
if (rs[indent] == 0)
|
||||
rs[indent] = lw
|
||||
}
|
||||
|
||||
# new section (must end with a cap letter to avoid tag list match)
|
||||
/^[A-Z ]+[A-Z]$/ {
|
||||
if (section == "SYNOPSIS")
|
||||
print ".fi"
|
||||
block_end()
|
||||
reset_indent()
|
||||
list = 0
|
||||
tplen = ""
|
||||
section = $1
|
||||
print (lw>0) ? ".SS" : ".SH", $0
|
||||
if (section == "SYNOPSIS") {
|
||||
print ".nf"
|
||||
print ".fam C"
|
||||
}
|
||||
if (section == "SEE")
|
||||
print ".nf"
|
||||
next
|
||||
}
|
||||
|
||||
section == "NAME" && name == "" && $1 != "" {
|
||||
name = $1
|
||||
# add(name, bold(name))
|
||||
sub(/ - /, " \\- ")
|
||||
}
|
||||
|
||||
section == "SYNOPSIS" {
|
||||
if (format == "") {
|
||||
block = lw # this is a pseudo-block; see new section
|
||||
if ($0 ~ /\(/) format = "code"
|
||||
else if ($1 == "struct" || $2 == "struct") format = "struct"
|
||||
else if ($1 == "union" || $2 == "union") format = "struct"
|
||||
else if ($1 == "class" || $2 == "class") format = "class"
|
||||
else if ($1 !~ /#|import|typedef|enum/) format = "cmd"
|
||||
}
|
||||
if (format == "cmd") {
|
||||
# cmd [-a N] [-b N] [-m ab] [-p S]
|
||||
# [-r] [-qst] @interface ip:port [filename ...]
|
||||
i = 1
|
||||
if ($1 !~ /^\[/) {
|
||||
++i
|
||||
a = $1
|
||||
gsub("-", "\\-", a)
|
||||
add(a, bold(a))
|
||||
}
|
||||
for (; i<=NF; ++i) {
|
||||
a = $i
|
||||
gsub(/[\[\]]/, "", a) # remove all brackets
|
||||
if (a == "-") ;
|
||||
else if (a ~ /^-./) add(a, bold("\\" a))
|
||||
else if (a !~ /\.\.\./) add(a, italic(a))
|
||||
}
|
||||
} else if (format == "code") {
|
||||
# void foo()
|
||||
# void foo(int);
|
||||
# void foo(int a);
|
||||
# void foo(int a, char *b);
|
||||
# void *foo(char **b, int *a, ...)
|
||||
# void (*signal(int sig, void (*func)(int)))(int);
|
||||
# ssize_t readv(int d, const struct iovec *iov, int iovcnt);
|
||||
if ($1 != "typedef")
|
||||
for (i = 1; i<=NF; ++i) {
|
||||
a = $i
|
||||
gsub("[\\*]", "", a) # dont want to mess with pointers
|
||||
if (match(a, "[A-Za-z0-9_]+\\(")) {
|
||||
a = substr(a, RSTART, RLENGTH-1)
|
||||
add(a, bold(a))
|
||||
} else if (match(a, "[A-Za-z0-9_]+[,\\)]")) {
|
||||
a = substr(a, RSTART, RLENGTH-1)
|
||||
add(a, italic(a))
|
||||
}
|
||||
}
|
||||
} else if (format == "struct") {
|
||||
if (match($0, "[A-Za-z0-9_]+[ ]*{")) {
|
||||
a = substr($0, RSTART)
|
||||
sub("[ ]*{", "", a);
|
||||
add(a, bold(a));
|
||||
}
|
||||
format = "code"
|
||||
} else if (format == "class") {
|
||||
# public class Foo extends Bar implements Snox, Blah, Nuts {
|
||||
# so remove from extends or implements, play as if C++
|
||||
a = $0
|
||||
if (match(a, "extends|implements"))
|
||||
a = substr(a, 1, RSTART-1)
|
||||
if (match(a, "[A-Za-z0-9_]+[ ]*{")) {
|
||||
a = substr(a, RSTART)
|
||||
sub("[ ]*{", "", a);
|
||||
add(a, bold(a));
|
||||
format = "code"
|
||||
}
|
||||
}
|
||||
replace()
|
||||
}
|
||||
|
||||
block == 0 {
|
||||
if (lw > rs[indent]+2) {
|
||||
if (blank == NR-1)
|
||||
block_start()
|
||||
else if (lw > list) {
|
||||
# XXX list?
|
||||
rs[++indent] = lw;
|
||||
print ".RS"
|
||||
}
|
||||
} else while (lw < rs[indent]) {
|
||||
print ".RE"
|
||||
--indent
|
||||
list = 0
|
||||
tplen = ""
|
||||
}
|
||||
}
|
||||
|
||||
block > 0 {
|
||||
if (lw < block)
|
||||
block_end()
|
||||
else {
|
||||
restore()
|
||||
print $0
|
||||
next
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
# if replace before matching, awk collapses multiple spaces into one....
|
||||
if (match($0, /[^ ] +/)) { # tag description
|
||||
list = lw + RSTART + RLENGTH
|
||||
tag = substr($0, 1, RSTART)
|
||||
def = substr($0, RSTART + RLENGTH)
|
||||
$0 = tag
|
||||
if (tplen == "" && def !~ /[.~]/)
|
||||
tplen = list-3
|
||||
replace()
|
||||
print ".TP " tplen "\n" bold($0)
|
||||
$0 = def
|
||||
|
||||
} else if (match($0, /^[o\.\*+] +/)) { # bullet list
|
||||
list = lw + RSTART + RLENGTH
|
||||
print ".IP \\(bu 3"
|
||||
$0 = substr($0, RLENGTH+1)
|
||||
|
||||
} else if (match($0, /^- +/)) { # dash list
|
||||
list = lw + RSTART + RLENGTH
|
||||
print ".IP \\(em 3"
|
||||
$0 = substr($0, RLENGTH+1)
|
||||
|
||||
} else if (match($0, /^[0-9]+\. +/)) { # number list
|
||||
list = lw + RSTART + RLENGTH
|
||||
print ".IP " $1 " 3"
|
||||
$0 = substr($0, RLENGTH+1)
|
||||
|
||||
} else {
|
||||
# the lists above supply their own vertical separation
|
||||
if (blank == NR-1)
|
||||
paragraph()
|
||||
}
|
||||
|
||||
# if there is anything left to print...
|
||||
if (length $0 > 0) {
|
||||
br = replace();
|
||||
if (length $0 > 0)
|
||||
print $0
|
||||
if (br) print ".br"
|
||||
}
|
||||
}
|
||||
' | eval $post
|
||||
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
awk '/^[^$]/{l=length;m=m>l?m:l;a[l]=a[l]$1}
|
||||
END{printf"\"";for(i=1;i<=m;++i)printf" "a[i];print"\""}' $*
|
||||
@@ -0,0 +1,63 @@
|
||||
--- iocccsize.orig.c 2018-01-13 10:01:16.000000000 -0600
|
||||
+++ iocccsize.c 2018-01-14 16:23:57.000000000 -0600
|
||||
@@ -181,6 +181,7 @@
|
||||
{ STRLEN("#ident"), "#ident" },
|
||||
{ STRLEN("#if"), "#if" },
|
||||
{ STRLEN("#ifdef"), "#ifdef" },
|
||||
+ { STRLEN("#ifndef"), "#ifndef" }, /* XXX bugfix */
|
||||
{ STRLEN("#include"), "#include" },
|
||||
{ STRLEN("#line"), "#line" },
|
||||
{ STRLEN("#pragma"), "#pragma" },
|
||||
@@ -225,7 +226,7 @@
|
||||
{ STRLEN("float"), "float" },
|
||||
{ STRLEN("for"), "for" },
|
||||
{ STRLEN("goto"), "goto" },
|
||||
- { STRLEN("I"), "I" },
|
||||
+ /* { STRLEN("I"), "I" }, */ /* XXX seriously? */
|
||||
{ STRLEN("if"), "if" },
|
||||
{ STRLEN("inline"), "inline" },
|
||||
{ STRLEN("int"), "int" },
|
||||
@@ -365,6 +366,7 @@
|
||||
int lcount, wcount, bcount;
|
||||
int is_comment, is_word, dquote, escape;
|
||||
int count, keywords, saved, kw_saved;
|
||||
+ int squote;
|
||||
|
||||
/* Start of buffer sentinel. */
|
||||
buf[0] = ' ';
|
||||
@@ -374,6 +376,7 @@
|
||||
keywords = kw_saved = 0;
|
||||
lcount = wcount = bcount = 0;
|
||||
is_comment = is_word = dquote = escape = 0;
|
||||
+ squote = 0;
|
||||
|
||||
/*
|
||||
* "no matter how well you may think you understand this code,
|
||||
@@ -422,6 +425,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ else if (squote) {
|
||||
+ if (escape)
|
||||
+ escape = 0;
|
||||
+ else if (*p == '\\')
|
||||
+ escape = 1;
|
||||
+ else if (*p == '\'')
|
||||
+ squote = 0;
|
||||
+ }
|
||||
+
|
||||
/* Not quote string. */
|
||||
else {
|
||||
/* In C comment block? */
|
||||
@@ -499,6 +511,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Open single quote string? */
|
||||
+ else if (*p == '\'') {
|
||||
+ squote = 1;
|
||||
+ }
|
||||
+
|
||||
/* Open quoted string? */
|
||||
else if (*p == '"') {
|
||||
dquote = 1;
|
||||
@@ -0,0 +1,67 @@
|
||||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#include<unistd.h>
|
||||
typedef unsigned char*_;
|
||||
_ s,i,z,e,O,F=
|
||||
#include W
|
||||
|
||||
"; ; } { { { { { } { { } ; } { ; ; { } ; { { } ; } ; { { { { } { { } \
|
||||
; } { { { { { } { ; } { } { { } { { } { { { ; ; { { } { { } { ; } { \
|
||||
} { { { { { } ; } { } { { } { { { \
|
||||
} { ; } { } { { { { { } ; } { } { \
|
||||
{ { } { { } ; ; { ; ; { { } { { } \
|
||||
{ ; } { } { { { } { } { { { ; { { \
|
||||
{ } { { } { { { { } { { { { { } ; \
|
||||
; { ; ; { { { { { } { ; } { } { { { { { } ; ; { ; ; { { ; { ; { { { \
|
||||
} { } { { { ; { ; { { { ; ; { } { { { } { ; } { } { { { { { } { { { \
|
||||
; ; { { } { ; { { { } { } { { { ; { ; { { { ; ; { { { { { } { { { { \
|
||||
\
|
||||
} { { { { { } ; } { } { { { { { { } { { { { } ; } ; { { { } \
|
||||
{ { { { { } { { } { { { } { { ; { { } { ; { { { { ; { { ; { \
|
||||
{ { { { } } { { ; { } { { { ; ; { \
|
||||
{ ; { ; { } { } ; { } { } ; { ; } { { { } { ; { } \
|
||||
{ ; { { { } { ; } } { ; ; { { } { ; ; } { ; ; ; { \
|
||||
} } { { } } { ; { { } } { } } } { \
|
||||
; } { } } { ; } } { ; ; { } } } { \
|
||||
{ { { { { } } } ; ; { } { ; ; } { ; } ; } { } { } } } { } { } { } \
|
||||
{ ; } { ; ; { } { } } { } { ; } } } { } } } } } } ; } } } } ; { } \
|
||||
{ } ; } } } } ; } } } ; { { } } } ; ; } } { { } } } ; { { " ; ; ; ;
|
||||
unsigned v,o,l,A,T,I,L,E,c,H,a,C,K,R,Z=256; char n,M[2053]; int*q; int h(_ F,int l) { for(;
|
||||
l--&&*F; putchar(*F++)); return 0; } int r(int I,int O){ return!fprintf(O&2?stderr:stdout
|
||||
,"%d%c",I,O&1?l:32); } int m(char O){ for(a=0; a-O&&z<e; L+=((a=*z++)==92?*z==a||*
|
||||
z==39||*z==
|
||||
34||*z==l?*
|
||||
z++:a:a)==l); return a; } int d(_ e,int l){ _ F=M+Z+q[l]; _ O=M+Z+q[n=-~l]; for(
|
||||
; l<*q&&n-l&&F<O; F+=l)for(n=0; n<l&&e[n]==F[n]; ++n); return l&&n==l?T +=--l,++K:0; }
|
||||
int j(){ for(c=0,o=Z,O=z; z<=e&&M[c=*z++]&16; ++C,L+=c==l); for(s=z-1; z>=e; )return C-=
|
||||
!c,c; for(a=M[c]; v&32&&c==35; )return m(l),o+2; for(; a&8; ){ for( ++o; M[c] &12; c=*z++);
|
||||
return d(s,--z-s)?o:++o; } for(; a&4; ){ for(c=c==48&&(*z|32)==120? *++z:c; M[c]&6; c=*z++)
|
||||
; return o+(c==46?strtod(s,(char**)&z),5:!--z^4); } for(; c==47&& (*z==c||*z==42); ){ for(;
|
||||
c==*z++; )return m(l),o; for(m(42); z<e &&*z++-47; --z, m(42)); return o; }
|
||||
return c==39||c==34?m(c),c:*z++==61&& a&64?c|128: a&128&&z[~0]==c?*z==61
|
||||
&&a&32&&c-45?++z,c|o|128:c|o:a&/* 2052 */32&&z[~0]==62?o+6:*--z?c:32; }
|
||||
void g(int l,int O){ for(c=0; c<l; ++c)(a=M[s[c]]&16)?--I:M[s
|
||||
[c]]&1&&M[s[c+1]]&16?--I:0, O=O ?!a:! a?++A:O; } void f(int T
|
||||
,int F){ int n; _ o=O; for (c= v&2; H==Z; L-=!(v&2 ||o[~0]
|
||||
-l),C-=o-O)for(H=0; o<s&& *o++ -l; ); O-=O==s &&O[~0]==l;
|
||||
T-=T==34||T==39? g(F,1), 0:Z ; a=O==s&&s>i; for(A-=T&&
|
||||
a&&M[O[-1]]-16,!(v&8)&& (T| c)?h(O,s-O), h(s,F):T; !T
|
||||
++; H=Z+s[1]-42){ for( n=a ; c; c^=c)for(I+=F,g(F,n
|
||||
),n=c=2; c<F&&s[1]==47 ; ++ c)a? (a=M[s[c]]&8)||d(s+
|
||||
n,c-n)&&(I-=c-++n):M[s [c] ]&8?a= n=c:a; for(c=v&2;
|
||||
!c;A+=!a&&M[s[F]]-16&& s[1]-47)for(c=0; c<F; ++
|
||||
c)L-=s[c]==l; for(o=s; o>O &&*--o-l; ); C-=*o==
|
||||
l||o==i||O[~0]==l?s-o- (*o==l):0; } } int b(int
|
||||
l){ for(a=0; l--; a+=c- 59?c==125:-~1) for(a+=a+
|
||||
a; (c=* F++)== 32||c==9; ); return a; } int main (
|
||||
int S,char**H){ for(s=e= M+Z,q= (int*)s,e+=Z/2; *F-
|
||||
59; *e++=*F++)for(; *F==32 ; ++F,q[++*q]=e-s); for(q[++
|
||||
*q]=e-s,z=M,v=b(3); v--; )for (z+= b(3),o= b(3),c=b(5); o--;
|
||||
*z++=c); for(*++e=l=10,O=s=M+4* Z,v=b (3); v--; O[o]=b(5))o=b(5)
|
||||
; for(O+=32,v=0; ~(a=getopt(S,H,O) ); )for(v|=s[a&31]; !(a ^~-Z >>2); )
|
||||
return h(U,~0); for(O+=32,a=0,o=2; c= getchar(),o<a|| (i=realloc(i ,a+=Z)),~c;
|
||||
i[o]=c,c==l+3?v&1&&++E: c==l&&i[~-o]==92 ?--o,++L,v&1?E+=2,++A:A:++o)O ??(c??)&&!(i??(??--o
|
||||
??)&i??(o-2??)??'63)?o-=2,E+=2,c=O??(c??):0; for(F=e,e=i+o,z=i+=2,*e=0; o=j(); v&1?f(o,a):v
|
||||
&8?v:v&2||o-Z?~v&32&&r(o,0),h(s,a),z[-1]-l&&h(F,1):0)a=z-s,o-Z?C+=a,++A,I+=v&4&&o==-~Z?1:M[
|
||||
o]==1&&(M[*z]==16||!*z)?0:a:a; a=e-O; a&&v&1?f(0,a),v&8||h(O,a):a; v&2?C=e-i:0; T*=v>>2&1;R
|
||||
=C-I-T; C+=E; return v&32?0:v&16?r(I,1):r(L,2)+r(A,2)+r(C,2)+r(I,2)+r(R,2)+r(K,2)+r(T,3); }
|
||||
@@ -0,0 +1,16 @@
|
||||
test01.c: 11 32 198 106 58 10 34
|
||||
test02.c: 1 5 37 29 8 0 0
|
||||
test03.c: 3 26 147 98 37 3 12
|
||||
test04.c: 6 12 88 47 16 5 25
|
||||
test05.c: 4 28 154 100 40 4 14
|
||||
test06.c: 7 10 74 41 24 2 9
|
||||
test07.c: 15 42 258 147 70 11 37
|
||||
test08.c: 11 32 198 106 58 10 34
|
||||
test09.c: 11 32 198 106 58 10 34
|
||||
test10.c: 7 15 163 94 17 6 18
|
||||
test11.c: 82 84 325 126 16 11 41
|
||||
test12.c: 6 10 73 41 23 2 9
|
||||
test13.c: 0 1 5 2 1 1 2
|
||||
test14.c: 4 8 62 41 12 2 9
|
||||
fixed_iocccsize.c: 408 1278 8781 5833 2464 156 484
|
||||
ioc_without_quote: 354 1383 7817 4488 2692 221 625
|
||||
@@ -0,0 +1,16 @@
|
||||
test01.c: 11 32 198 106 58 10 34
|
||||
test02.c: 14 39 241 173 68 0 0
|
||||
test03.c: 3 26 147 98 37 3 12
|
||||
test04.c: 6 12 88 47 16 5 25
|
||||
test05.c: 4 31 167 107 46 4 14
|
||||
test06.c: 7 14 95 53 33 2 9
|
||||
test07.c: 16 46 291 173 77 11 37
|
||||
test08.c: 12 38 224 120 70 10 34
|
||||
test09.c: 13 38 232 130 68 10 34
|
||||
test10.c: 7 15 163 94 17 6 18
|
||||
test11.c: 82 84 325 126 16 11 41
|
||||
test12.c: 7 10 89 51 29 2 9
|
||||
test13.c: 0 1 5 2 1 1 2
|
||||
test14.c: 4 8 73 52 12 2 9
|
||||
fixed_iocccsize.c: 637 2723 16904 12007 4369 168 528
|
||||
ioc_without_quote: 396 1740 9917 6135 3097 247 673
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
: ${prog:=./prog}
|
||||
: ${opt:=crs}
|
||||
|
||||
exec 2>&1
|
||||
for name in test*c fixed_iocccsize.c ioc_without_quote; do
|
||||
/bin/echo -n "$name: "; $prog -$opt < $name
|
||||
done
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/bin/sh
|
||||
|
||||
ioc=$1
|
||||
: ${iocccsize:=iocccsize}
|
||||
: ${ioc:=prog}
|
||||
|
||||
opt=-crs
|
||||
kopt=-kcrs
|
||||
|
||||
for name in $*; do
|
||||
|
||||
if test $name != $ioc; then
|
||||
|
||||
a=$($ioc $opt < $name 2>&1)
|
||||
b=$($iocccsize $opt < $name 2>&1)
|
||||
if test "$a" != "$b"; then
|
||||
echo $a , $b , $name
|
||||
fi
|
||||
|
||||
a=$($ioc $kopt < $name 2>&1)
|
||||
b=$($iocccsize $kopt < $name 2>&1)
|
||||
if test "$a" != "$b"; then
|
||||
echo $a , $b , $name " keep"
|
||||
fi
|
||||
|
||||
fi
|
||||
done
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
# filename is 17
|
||||
# 1=cl 2=cw 3=cc 4=ci 5=ts 6=kw 7=kws
|
||||
# 9 10 11 12 13 14 15
|
||||
awk '{
|
||||
printf "cl %d cw %d cc %d ci %d ts %d kw %d ks %d %s %s\n",
|
||||
$9-$1, $10-$2, $11-$3, $12-$4, $13-$5, $14-$6, $15-$7, $17, $18
|
||||
}'
|
||||
@@ -0,0 +1,81 @@
|
||||
zrzbel znc: Z (bssfrg, yratgu)
|
||||
0,256 gbxravmngvba syntf
|
||||
256,128 xrljbeq yratgu bssfrg znc
|
||||
384,640 xrljbeq fgevatf (453 punef)
|
||||
1024,32 bcgvba ovg znc
|
||||
1056,32 trgbcg fgevat
|
||||
1088,256 gevtencu znc
|
||||
|
||||
serrpbqr: gevanel, nycunorg 0 { 1 } 2 ;
|
||||
hfvat guerr gevgf, gur nycunorg N-M jvgu n fcnpr/ahyy pna or rapbqrq:
|
||||
0 fcnpr/ahyy, 1 N, 2 O, 3 P, ...
|
||||
nygubhtu guvf rapbqvat vf abg gur bayl bar
|
||||
pbqr vf serr-sbez, fcnpr ntabfgvp (bar be zber fcnprf ner erdhverq sbe vg gb or 'serr')
|
||||
qrpbqvat vf pbagrkg qrcraqrag, glcvpnyyl hfvat 3 be zber gevgf
|
||||
gur cebtenz pbzzragf hfr o(3) naq gur nycunorg rapbqvat nobir,
|
||||
ohg gurl ner abg pyrnayl fcyvg ba 3-gevg obhaqnevrf(!)
|
||||
|
||||
v N pj
|
||||
O
|
||||
v P pp
|
||||
Q
|
||||
v R pk
|
||||
c S[] xrljbeqf, gbxra vavg, bcgvbaf vavg, bcgvba fgevat, gevtencu vavg
|
||||
T
|
||||
v U pbzzrag uvfgbel
|
||||
v V pv
|
||||
W
|
||||
v X px
|
||||
v Y py
|
||||
p Z[2053] zrzbel: gbxra syntf, xrljbeq gnoyr, bcgvba gnoyr, gevtencu gnoyr
|
||||
A
|
||||
c B fgneg bs juvgrfcnpr
|
||||
C
|
||||
D
|
||||
v E gf
|
||||
F
|
||||
v G gx
|
||||
q H qrsvarq hfntr zrffntr (-QH="\"uryc grkg\"")
|
||||
I
|
||||
q J qrsvarq erfreirq jbeq fgevat (-QJ=\"xrljbeqf\")
|
||||
K
|
||||
L
|
||||
v M 256
|
||||
v n tybony
|
||||
v o(v) qrpbqr serrpbqr hfvat v ovgf
|
||||
v p tybony
|
||||
v q(f,v) vf n xrljbeq?
|
||||
c r raq bs ohssre
|
||||
i s(v,v) pbzcng
|
||||
i t(v,v) pbzcng_jbeqf
|
||||
v u(f,v) cevag v punef bs f, be hagvy ahyy
|
||||
c v ohssre
|
||||
v w() yrkre
|
||||
x
|
||||
v y 10 / arjyvar
|
||||
v z(p) jnag(p), unaqyrf rfpncrf
|
||||
a tybony
|
||||
v b tybony
|
||||
c
|
||||
c d xrljbeq vaqrk gnoyr
|
||||
v e(v,v) cevag net1 nf vag gb fgqbhg/ree ol net2, genvyrq ol fcnpr/arjyvar
|
||||
f fgneg bs gbxra
|
||||
g
|
||||
h
|
||||
v i pzq yvar syntf
|
||||
j
|
||||
k
|
||||
l
|
||||
c m pheerag cbvagre
|
||||
|
||||
shapgvbaf
|
||||
|
||||
v u(f,v) cevag v punef bs f, be hagvy ahyy
|
||||
v e(v,v) cevag net1 nf vag gb fgqbhg/ree ol net2, genvyrq ol fcnpr/arjyvar
|
||||
v z(p) jnag(p), unaqyrf rfpncrf
|
||||
v q(f,v) vf n xrljbeq?
|
||||
v w() yrkre
|
||||
i t(v,v) pbzcng_jbeqf
|
||||
i s(v,v) pbzcng
|
||||
v o(v) qrpbqr serrpbqr hfvat v ovgf
|
||||
v znva(p,cc) vavg, bcgvbaf, ernq, pbhag, cevag
|
||||
@@ -0,0 +1,509 @@
|
||||
/*
|
||||
* tac - tokenize and count C-like languages
|
||||
*
|
||||
* tac is offered as a replacement for iocccsize.
|
||||
* Version 2018.04.18
|
||||
* Public Domain 2015 by Dave Burton.
|
||||
* Please keep this attribution with the source code.
|
||||
*
|
||||
* cc -O3 -DW=\"keywords\" -Wall -pedantic -o tac tac.c
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* The keywords recognized by tac should be defined in an external file,
|
||||
* filtered by the following script into a new file, and #included
|
||||
* by defining the preprocessor variable W as this new file.
|
||||
*
|
||||
* The input to the script is a list of keywords, one word per line,
|
||||
* in any order. The output is a single string suitable for tac.
|
||||
* --------------------------------------------------
|
||||
|
||||
#!/bin/sh
|
||||
awk '/^[^$]/{l=length;m=m>l?m:l;a[l]=a[l]$1}
|
||||
END{printf"\"";for(i=1;i<=m;++i)printf" "a[i];print"\""}' $*
|
||||
|
||||
* --------------------------------------------------
|
||||
* The pre-defined string below is the IOCCC reserved word list for 2016.
|
||||
* It was created by the above script, then inserted here in case the
|
||||
* source keywords file is not available.
|
||||
*
|
||||
* The format of the keyword string is precise; addition or removal of
|
||||
* a single character will cause improper operation.
|
||||
*
|
||||
* DO NOT EDIT the string kw; instead:
|
||||
*
|
||||
* mkkeywords < my.list > my.keywords
|
||||
* cc -DW=\"my.keywords\" -o tac tac.c
|
||||
*/
|
||||
|
||||
char *keywords = ""
|
||||
#ifndef W
|
||||
|
||||
" ifdoor intfor#ifandnotxor voidcharelsegotocaselongenumautobooltr\
|
||||
ue whilebreakconstfloatshortunion#else#elif#line_Boolfalsecomplbito\
|
||||
ror_eq returnsizeofstructdoubleswitchstaticexternsigned#ifdef#endif\
|
||||
inline#errorbitandand_eqnot_eqxor_eq typedefdefault#ifndef#pragma_A\
|
||||
tomic_Pragmaalignasalignof #includeunsignedcontinuevolatileregister\
|
||||
restrict#warning_Complex_Generic_Alignas_Alignofnoreturn _Noreturn \
|
||||
_Imaginary thread_local _Thread_localstatic_assert _Static_assert"
|
||||
|
||||
#else
|
||||
# include W
|
||||
# undef W
|
||||
#endif
|
||||
;
|
||||
|
||||
int cline, cword, cbyte, cioccc, ckey, cextra; // counts
|
||||
int tsaved, tkey; // totals
|
||||
int fkeep, fsuppress, freserved, fioccc, fcompat, ftoken; // flags
|
||||
|
||||
unsigned char *buf, *cur, *end, *white, *start;
|
||||
|
||||
enum {
|
||||
CPP = 256
|
||||
, CMT = 257
|
||||
, KEYW = 258
|
||||
, DIVEQ = 259
|
||||
, MULEQ = 260
|
||||
, MODEQ = 261
|
||||
, ADDEQ = 262
|
||||
, SUBEQ = 263
|
||||
, XOREQ = 264
|
||||
, OREQ = 265
|
||||
, ANDEQ = 266
|
||||
, RSHEQ = 267
|
||||
, LSHEQ = 268
|
||||
, NOTEQ = 269
|
||||
, EQ = 270
|
||||
, GE = 271
|
||||
, LE = 272
|
||||
, OR2 = 273
|
||||
, AND2 = 274
|
||||
, PP = 275
|
||||
, MM = 276
|
||||
, PTR = 277
|
||||
, LSH = 278
|
||||
, RSH = 279
|
||||
, INT = 300
|
||||
, FLOAT = 301
|
||||
, ID = 302
|
||||
, DOT3 = 303
|
||||
};
|
||||
|
||||
enum {
|
||||
O=0x01 // octal
|
||||
, H=0x02 // hex
|
||||
, D=0x04 // decimal
|
||||
, I=0x08 // identifier
|
||||
, W=0x10 // whitespace
|
||||
, B=0x20 // brace, semi
|
||||
, OHD = O|H|D
|
||||
, HD = H|D
|
||||
, HI = H|I
|
||||
};
|
||||
|
||||
char tab[256] = {
|
||||
W, 00, 00, 00, 00, 00, 00, 00, 00, W, W, W, W, W, 00, 00,
|
||||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||||
W, 00, 00, I, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||||
OHD,OHD,OHD,OHD,OHD,OHD,OHD,OHD, HD, HD, 00, B, 00, 00, 00, 00,
|
||||
|
||||
00, HI, HI, HI, HI, HI, HI, I, I, I, I, I, I, I, I, I,
|
||||
I, I, I, I, I, I, I, I, I, I, I, 00, 00, 00, 00, I,
|
||||
00, HI, HI, HI, HI, HI, HI, I, I, I, I, I, I, I, I, I,
|
||||
I, I, I, I, I, I, I, I, I, I, I, B, 00, B, 00, 00,
|
||||
};
|
||||
|
||||
char tri[256] = {
|
||||
['='] = '#',
|
||||
['('] = '[',
|
||||
['/'] = '\\',
|
||||
[')'] = ']',
|
||||
['\'']= '^',
|
||||
['<'] = '{',
|
||||
['!'] = '|',
|
||||
['>'] = '}',
|
||||
['-'] = '~',
|
||||
};
|
||||
|
||||
#define is(x, c) (tab[c]&(x))
|
||||
|
||||
/*
|
||||
* discard backslash-newline as-if not present, even if trigraph backslash
|
||||
* iocccsize counts tri as xbcount+=2,
|
||||
* and bs-nl as xb+=2, xw++, xl++ to match wc(1)
|
||||
*/
|
||||
|
||||
void readsource() {
|
||||
int c, d, o=2, len=4096;
|
||||
buf = malloc(len);
|
||||
while ((c = getchar()) != EOF) {
|
||||
if (c == '\r') {
|
||||
if (fcompat) ++cextra;
|
||||
continue;
|
||||
}
|
||||
if (buf[o-1] == '?' && buf[o-2] == '?' && tri[c]) {
|
||||
c = tri[c];
|
||||
o -= 2;
|
||||
if (fcompat) cextra += 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* digraph support:
|
||||
* translating digraphs after trigraphs is,
|
||||
* for the purposes of this code, essentially during tokenization.
|
||||
*/
|
||||
d = c;
|
||||
switch (buf[o-1]) {
|
||||
case '<': d = (c == ':' ? '[' : c == '%' ? '{' : c); break;
|
||||
case '%': d = (c == '>' ? '}' : c == ':' ? '#' : c); break;
|
||||
case ':': d = (c == '>' ? ']' : c); break;
|
||||
}
|
||||
if (c != d) {
|
||||
c = d;
|
||||
o--;
|
||||
if (fcompat) ++cextra;
|
||||
}
|
||||
|
||||
if (c == '\n' && buf[o-1] == '\\') {
|
||||
--o;
|
||||
cline++;
|
||||
if (fcompat) {
|
||||
++cword;
|
||||
cextra += 2;
|
||||
}
|
||||
} else
|
||||
buf[o++] = c;
|
||||
if (o == len)
|
||||
buf = realloc(buf, len+=4096);
|
||||
}
|
||||
buf[o] = 0;
|
||||
end = buf + o;
|
||||
cur = buf += 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* keyword recognition: kw is sorted by length, space separated between lengths
|
||||
* e.g. " ifdo forint#if charvoidelsegoto..."
|
||||
* build a table of offsets for each length
|
||||
* e.g. [0]0, [1]1, [2]2, [3]7, [4]17, ...
|
||||
* this allows scans for only words of same length instead of entire list
|
||||
* trade-off is a small, but constant start-up cost to get a configurable
|
||||
* word list (backported from obfuscated code: it was too nice to give up)
|
||||
*/
|
||||
|
||||
int nkwoff, kwoff[32]; // allows keywords up to 32 characters in length
|
||||
|
||||
void kwinit() {
|
||||
char *k = keywords;
|
||||
for (nkwoff = 0; *k; ++k)
|
||||
while (*k == ' ')
|
||||
kwoff[++nkwoff] = ++k - keywords;
|
||||
kwoff[++nkwoff] = ++k - keywords;
|
||||
}
|
||||
|
||||
int iskw(unsigned char *s, int len) {
|
||||
int found = 0;
|
||||
if (len < nkwoff) {
|
||||
char *off = keywords + kwoff[len];
|
||||
char *end = keywords + kwoff[len + 1] - 1;
|
||||
for (; !found && off < end; off += len)
|
||||
found = *s == *off && !strncmp((char*)s, off, len);
|
||||
if (found) {
|
||||
++ckey;
|
||||
tkey += len - 1;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
int want(char m) {
|
||||
while (cur < end) {
|
||||
if (*cur == '\\') {
|
||||
/*
|
||||
* need to only ignore: ntbrfv\'"a?, octal, x, hex
|
||||
* 0111 = two chars, \091 = three, \xabc = one char(!)
|
||||
* for our purposes, only need: ' " and \ newline,
|
||||
* but readsource eats \ newline, so only quotes here
|
||||
*/
|
||||
if (cur[1] == '\\' || cur[1] == '\'' || cur[1] == '"') {
|
||||
cur += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (*cur == '\n') ++cline;
|
||||
if (*cur++ == m) return m;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int follow(char m, int y, int n) {
|
||||
if (*cur == m) return ++cur,y;
|
||||
return n;
|
||||
}
|
||||
|
||||
int follow2(char m, int y, int n, int y2) {
|
||||
if (*cur == m) return ++cur,y;
|
||||
if (*cur == n) return ++cur,y2;
|
||||
return n;
|
||||
}
|
||||
|
||||
int skipwhite() {
|
||||
int c;
|
||||
for (c=*cur++; cur<=end && is(W, c); c=*cur++) {
|
||||
++cbyte;
|
||||
if (c == '\n') ++cline;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
* CPP tokens may extend beyond a single line of text and include comments
|
||||
* To do this correctly, need to scan and remove comments during readsource
|
||||
* and present comments as whitespace. Note that "# include" is a valid CPP
|
||||
* token, and does not match "#include".
|
||||
*
|
||||
* Because the global pointers cur, start and white are well-known, and
|
||||
* because comments are not consumed during readsource, it is more difficult
|
||||
* to parse CPP stuff. Also note that for backwards compat, we need to also
|
||||
* count words correctly, with and without -k.
|
||||
*/
|
||||
|
||||
int lex() {
|
||||
int c, t;
|
||||
|
||||
white = cur;
|
||||
c = skipwhite();
|
||||
start = cur-1;
|
||||
|
||||
if (cur >= end)
|
||||
return c;
|
||||
|
||||
switch (c) {
|
||||
case '\'': want(c); return c;
|
||||
case '"': want(c); return c;
|
||||
case '/':
|
||||
t = follow2('=', DIVEQ, c, CMT);
|
||||
if (t == CMT)
|
||||
want('\n');
|
||||
else if (t == c && (t = follow('*', CMT, c)) == CMT)
|
||||
do want('*'); while (cur<end && follow('/', 0, 1));
|
||||
return t;
|
||||
case '*': return follow ('=', MULEQ, c);
|
||||
case '%': return follow ('=', MODEQ, c);
|
||||
case '=': return follow ('=', EQ, c);
|
||||
case '!': return follow ('=', NOTEQ, c);
|
||||
case '^': return follow ('=', XOREQ, c);
|
||||
case '|': return follow2('=', OREQ, c, OR2);
|
||||
case '&': return follow2('=', ANDEQ, c, AND2);
|
||||
case '+': return follow2('=', ADDEQ, c, PP);
|
||||
case '-': t = follow2('=', SUBEQ, c, MM);
|
||||
return t==c? follow ('>', PTR, t) : t;
|
||||
case '>': t = follow2('=', GE, c, RSH);
|
||||
return t==RSH? follow ('=', RSHEQ, t) : t;
|
||||
case '<': t = follow2('=', LE, c, LSH);
|
||||
return t==LSH? follow ('=', LSHEQ, t):t;
|
||||
|
||||
case '#': if (ftoken || !fcompat) return want('\n'), CPP;
|
||||
case '.': if (cur[0] == c && cur[1] == c) return cur+=2, DOT3;
|
||||
}
|
||||
|
||||
if (is(D, c)) {
|
||||
if (c == '0' && (*cur|32) == 'x')
|
||||
c = *++cur;
|
||||
while (is(OHD, c))
|
||||
c = *cur++;
|
||||
if (c == '.' || (c|32) == 'e') {
|
||||
(void)strtod((char*)start, (char**)&cur); // find end of float
|
||||
return FLOAT;
|
||||
}
|
||||
return --cur, INT;
|
||||
}
|
||||
|
||||
if (is(I, c)) {
|
||||
while (is(I|D, c))
|
||||
c = *cur++;
|
||||
--cur;
|
||||
return iskw(start, cur-start) ? KEYW : ID;
|
||||
}
|
||||
|
||||
return c ? c : ' '; // allows nulls in source code
|
||||
}
|
||||
|
||||
// iocccsize compat: adjust whitespace counts
|
||||
void compat_words(int tlen, int inword) {
|
||||
int c;
|
||||
for (c=0; c<tlen; ++c) {
|
||||
int isw = is(W,start[c]);
|
||||
if (isw || (is(B,start[c]) && is(W,start[c+1])))
|
||||
--cioccc;
|
||||
if (inword) inword = !isw;
|
||||
else if (!isw) inword = ++cword;
|
||||
}
|
||||
}
|
||||
|
||||
void compat_kw(int tlen, int inword) {
|
||||
int c, w=0;
|
||||
for (w=c=2; c<tlen; ++c) { // skip comment lead-in chars
|
||||
int isw = !is(I|D,start[c]);
|
||||
if (inword) {
|
||||
inword = !isw;
|
||||
if (!inword && iskw(start+w, c-w))
|
||||
cioccc -= c-w-1;
|
||||
} else if (!isw)
|
||||
inword = w = c;
|
||||
}
|
||||
}
|
||||
|
||||
void compat(int t, int tlen) {
|
||||
static int tprev;
|
||||
int c;
|
||||
if (tprev == CMT) {
|
||||
/*
|
||||
* do not bcount spaces following comment blocks,
|
||||
* including the newline! nor lcount the newline following
|
||||
* a comment block if last on line
|
||||
*/
|
||||
unsigned char *ow = white;
|
||||
while (ow<start && *ow++ != '\n')
|
||||
;
|
||||
if (!fkeep && ow[-1] == '\n')
|
||||
--cline;
|
||||
cbyte -= ow-white;
|
||||
tprev = 0;
|
||||
}
|
||||
// new-style comments eat preceding newline,
|
||||
// leaving no whitespace if token starts line
|
||||
// add it back here for compat word boundary detection
|
||||
if (white == start && white[-1] == '\n')
|
||||
--white;
|
||||
if (t == CMT) {
|
||||
// do not count newlines within comments
|
||||
// and checks for keywords in new-style comments
|
||||
if (fkeep) {
|
||||
int inword = white==start && start>buf;
|
||||
cioccc += tlen;
|
||||
if (start[1] == '/')
|
||||
compat_kw(tlen, inword);
|
||||
compat_words(tlen, inword);
|
||||
} else for (c=0; c<tlen; ++c)
|
||||
if (start[c] == '\n') --cline;
|
||||
|
||||
// nor spaces before comments IFF the comment
|
||||
// is first non-white on line
|
||||
unsigned char *os = start;
|
||||
while (os > white) {
|
||||
if (*--os == '\n')
|
||||
break;
|
||||
}
|
||||
|
||||
// look for last ends with newline,
|
||||
// only remove ccounts if whitespace
|
||||
if (*os == '\n' || os == buf || white[-1] == '\n')
|
||||
cbyte -= start - os - (*os == '\n');
|
||||
|
||||
// look for whitespace before the comment, as well as after
|
||||
if (!fkeep
|
||||
&& (white != start || start == buf)
|
||||
&& !is(W, start[tlen]) && start[1] == '*')
|
||||
++cword;
|
||||
|
||||
if (start[1] == '*')
|
||||
tprev = CMT;
|
||||
} else if (t == '"' || t == '\'') {
|
||||
// iocccsize -i does not count whitespace WITHIN a string!!!
|
||||
// and {;} can be "free" within a string if follows the "rules"
|
||||
compat_words(tlen, 1);
|
||||
}
|
||||
// count words, not tokens (a preceding old-style CMT is whitespace)
|
||||
if (t && t != CMT && white == start && start > buf)
|
||||
--cword;
|
||||
if (!fsuppress && (t != CMT || fkeep))
|
||||
printf("%.*s", (int)(start-white)+tlen, white);
|
||||
}
|
||||
|
||||
void count() {
|
||||
int t, tlen;
|
||||
kwinit();
|
||||
while ((t=lex())) {
|
||||
tlen = cur-start;
|
||||
if (t != CMT) {
|
||||
cbyte += tlen;
|
||||
++cword;
|
||||
if (freserved && t == KEYW)
|
||||
cioccc += 1;
|
||||
else if (t < 256 && is(B, t) && (is(W, *cur) || !*cur))
|
||||
;
|
||||
else
|
||||
cioccc += tlen;
|
||||
}
|
||||
if (fcompat)
|
||||
compat(t, tlen);
|
||||
else if (!fsuppress && (t != CMT || fkeep)) {
|
||||
if (!ftoken) printf("%3d ", t);
|
||||
printf("%.*s", tlen, start);
|
||||
if (cur[-1] != '\n') printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (fcompat) {
|
||||
// process comments just before end of file
|
||||
compat(0, end-white);
|
||||
}
|
||||
|
||||
if (fkeep) cbyte = end - buf;
|
||||
if (!freserved) tkey = 0;
|
||||
tsaved = cbyte - cioccc - tkey;
|
||||
cbyte += cextra;
|
||||
}
|
||||
|
||||
int main(int ac, char **av) {
|
||||
static char usage[] = "[flags] [file]\n\
|
||||
-t tokenize input\n\
|
||||
-c compatible count and display token ids\n\
|
||||
-k keep comments\n\
|
||||
-s suppress source\n\
|
||||
-r reserved words count as 1\n\
|
||||
-i ioccc size (implies -rs)\n\
|
||||
-h this help";
|
||||
|
||||
fcompat = 1; // default: compact with iocccsize: invert sense of -c
|
||||
|
||||
int c;
|
||||
while ((c = getopt(ac, av, "?tcksrih")) != EOF) {
|
||||
switch (c) {
|
||||
case 't': ftoken = 1; // fallthru - -t implies -c
|
||||
case 'c': fcompat = 0; break;
|
||||
case 'k': fkeep = 1; break;
|
||||
case 's': fsuppress = 1; break;
|
||||
case 'r': freserved = 1; break;
|
||||
case 'i': fioccc = freserved = fsuppress = fcompat = 1; break;
|
||||
case 'h': // fallthru, alias for -?
|
||||
default:
|
||||
fprintf(stderr, "%s %s\n", av[0], usage);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
ac -= optind;
|
||||
av += optind;
|
||||
if (ac > 0 && !freopen(*av, "r", stdin)) {
|
||||
perror(*av);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
readsource();
|
||||
count();
|
||||
|
||||
if (!ftoken) {
|
||||
if (fioccc) printf("%d\n", cioccc);
|
||||
else fprintf(stderr, "%d %d %d %d %d %d %d\n",
|
||||
cline,cword,cbyte,cioccc,tsaved,ckey,tkey);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
NAME
|
||||
tac - tokenize and count C-like program source code
|
||||
|
||||
SYNOPSIS
|
||||
tac [-t] [-c] [-k] [-r] [-s] [-i] [file]
|
||||
|
||||
DESCRIPTION
|
||||
tac reads C or C-like source code from stdin or file, breaking it into tokens (lexemes),
|
||||
counting these according to the rules of the IOCCC, and outputting the tokens,
|
||||
counts, or source code as directed by the command line options.
|
||||
The default output is the source code with comments removed on stdout,
|
||||
and the counts on stderr.
|
||||
|
||||
The count format is a set of integer values in the following order:
|
||||
|
||||
lines number of newlines
|
||||
words number of words
|
||||
chars number of characters
|
||||
ioccc number of IOCCC countable tokens; the IOCCC rule 2 value
|
||||
saved number of characters not counted due to rules and keywords
|
||||
kwcnt number of keywords
|
||||
kwlen number of characters saved by counting keyword length as 1
|
||||
|
||||
For the following code:
|
||||
|
||||
#include <stdio.h>
|
||||
int main() {
|
||||
/* example for loop */
|
||||
for (int ac=1; ac<10; ++ac)
|
||||
printf("%d\n", ac);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tac prints the code to stdout, and to stderr:
|
||||
|
||||
6 15 96 71 25 5 0
|
||||
|
||||
which means 6 lines, 15 words, 96 chars, 71 IOCCC counts, 25 chars saved,
|
||||
5 kwcnt, and no characters saved from kwlen. (By default, comments are not
|
||||
counted.)
|
||||
|
||||
The following options are supported:
|
||||
|
||||
-t output just the token stream
|
||||
-c correct the accounting bugs in iocccsize(1), output the token id and the token
|
||||
-k keep the comments
|
||||
-r reserved words count as size 1
|
||||
-s suppress the source code, summarize counts only
|
||||
-i report only the official IOCCC rule 2 size: number of octets (implies -r and -s)
|
||||
|
||||
Counts are impacted by the -k, -r and -c options.
|
||||
By default, the counts do not include comments, words are counted as in wc(1),
|
||||
and reserved words count in full.
|
||||
Using the example code above, the options change the counts as follows:
|
||||
|
||||
-r 6 15 96 53 25 5 18
|
||||
-k 7 20 120 89 31 5 0
|
||||
-c 7 36 98 71 27 5 0
|
||||
|
||||
The -c option counts tokens instead of words, and is therefore more accurate for source code.
|
||||
Note the aberration for line count with -r; it is as-if the comment never existed.
|
||||
|
||||
The -c and -t options change the output, instead writing a stream of tokens to stdout,
|
||||
one token per line.
|
||||
The -t option suppresses both the counts and the token ids, writing only the tokens.
|
||||
|
||||
EXAMPLES
|
||||
Summarize the source code counts:
|
||||
|
||||
tac -rs tac.c
|
||||
|
||||
Count the 10 most frequently used unique tokens in the source code:
|
||||
|
||||
tac -t tac.c 2>/dev/null | sort | uniq -c | sort -k1nr | sed 10q
|
||||
|
||||
Count the unique constants in the source:
|
||||
|
||||
tac -c tac.c 2>/dev/null | grep ^300 | sort | uniq -c | sort -k1nr | awk '{print $1,$3}'
|
||||
|
||||
BUGS
|
||||
tac does not properly count preprocessor tokens with embedded space or
|
||||
comments as reserved words:
|
||||
|
||||
echo '#/*comment*/include/*comment*/<stdio.h>' | tac -i
|
||||
echo '# include<stdio.h>' | tac -i
|
||||
echo '#include<stdio.h>' | tac -i
|
||||
|
||||
reports no reserved words on the first two inputs, and thus 17 as the IOCCC size,
|
||||
although 10 is the correct answer (as in the final example).
|
||||
|
||||
The original meaning of the -c option was "become compatible with iocccsize(1)".
|
||||
Its meaning was flipped so the default behavior is now compatible.
|
||||
|
||||
SEE ALSO
|
||||
iocccsize(1), wc(1)
|
||||
http://ioccc.org/2015/rules.txt
|
||||
@@ -0,0 +1,11 @@
|
||||
main(int ac, char **av) {
|
||||
if (av[0][0] == '"') {
|
||||
switch (av[0][1]) {
|
||||
case 'a': printf("a\n"); break;
|
||||
case 'b': printf("b\n"); break;
|
||||
}
|
||||
}
|
||||
while (--ac > 0)
|
||||
printf("%d", ac);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
main(int ac, char **av) {
|
||||
if (av[0][0] == '"') {
|
||||
switch (av[0][1]) {
|
||||
case 'a': printf("a\n"); break;
|
||||
case 'b': printf("b\n"); break;
|
||||
}
|
||||
}
|
||||
while (--ac > 0)
|
||||
printf("%d", ac);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
main() { printf("hello, world\n"); }
|
||||
@@ -0,0 +1,3 @@
|
||||
#include <stdio.h>
|
||||
char a[] = "main() { return printf(\" hello, world!\n\" \" } ; // this is not a comment";
|
||||
int main() { printf("%s\n", a); }
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef FOO
|
||||
#include <stdio.h>
|
||||
int main() {
|
||||
return printf("hello, world!\n");
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,4 @@
|
||||
#include <stdio.h>
|
||||
/* one */ int b;
|
||||
char a[] = "main() { return printf(\" hello, world!\n\" \" } ; // this is not a comment";
|
||||
int main() { printf("%s\n", a); }
|
||||
@@ -0,0 +1,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
/* a comment */ printf(
|
||||
"hello, world!\n"
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// leading whitespace comment
|
||||
main(int ac, char **av) {
|
||||
char foo[] = "line one\n\
|
||||
two\n\
|
||||
three\n";
|
||||
if (av[0][0] == '"') {
|
||||
switch (av[0][1]) {
|
||||
case 'a': printf("a\n"); break;
|
||||
case 'b': printf("b\n"); break;
|
||||
}
|
||||
}
|
||||
while (--ac > 0)
|
||||
printf("%d", ac);
|
||||
printf(foo);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/* one */ /* two */
|
||||
main(int ac, char **av) {
|
||||
if (av[0][0] == '"') {
|
||||
switch (av[0][1]) {
|
||||
case 'a': printf("a\n"); break;
|
||||
case 'b': printf("b\n"); break;
|
||||
}
|
||||
}
|
||||
while (--ac > 0)
|
||||
printf("%d", ac);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
main(int ac, char **av) {
|
||||
if (av[0][0] == '"') {
|
||||
switch (av[0][1]) {
|
||||
case 'a': printf("a\n"); break;
|
||||
case 'b': printf("b\n"); break;
|
||||
}
|
||||
}
|
||||
// comment one
|
||||
// comment two
|
||||
while (--ac > 0)
|
||||
printf("%d", ac);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
??=include <stdio.h>
|
||||
??/
|
||||
int main(int ac, char **av)??<
|
||||
if (!(ac??'1))??<printf("hello, world?????/n");
|
||||
??>else??<pr??/
|
||||
intf("hello,%s!??/n", av??(1??));??>
|
||||
??>
|
||||
@@ -0,0 +1,82 @@
|
||||
#i\
|
||||
nc\
|
||||
lu\
|
||||
de\
|
||||
<s\
|
||||
td\
|
||||
io\
|
||||
.h>
|
||||
|
||||
ma\
|
||||
in(
|
||||
in\
|
||||
t \
|
||||
ac\
|
||||
, \
|
||||
ch\
|
||||
ar\
|
||||
**\
|
||||
av)
|
||||
{i\
|
||||
f(\
|
||||
av\
|
||||
[0\
|
||||
][\
|
||||
0]\
|
||||
==\
|
||||
'"\
|
||||
')\
|
||||
{s\
|
||||
wi\
|
||||
tc\
|
||||
h(\
|
||||
av\
|
||||
[0\
|
||||
][\
|
||||
1]\
|
||||
){\
|
||||
ca\
|
||||
se\
|
||||
'a\
|
||||
':\
|
||||
pr\
|
||||
in\
|
||||
tf\
|
||||
("\
|
||||
a\\
|
||||
n"\
|
||||
);\
|
||||
br\
|
||||
ea\
|
||||
k;\
|
||||
ca\
|
||||
se\
|
||||
'b\
|
||||
':\
|
||||
pr\
|
||||
in\
|
||||
tf(
|
||||
"b\
|
||||
\n\
|
||||
");
|
||||
br\
|
||||
ea\
|
||||
k;\
|
||||
}}\
|
||||
wh\
|
||||
il\
|
||||
e(\
|
||||
--\
|
||||
ac>
|
||||
0)\
|
||||
pr\
|
||||
in\
|
||||
tf(
|
||||
"%\
|
||||
d",
|
||||
ac)
|
||||
;r\
|
||||
et\
|
||||
ur\
|
||||
n \
|
||||
0;}
|
||||
@@ -0,0 +1,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
/***/printf(/***/
|
||||
"hello, world!\n"
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{int}
|
||||
@@ -0,0 +1,4 @@
|
||||
#include <stdio.h>
|
||||
int main() {
|
||||
printf/*testing*/("hello, world!\n");
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/bin/sh
|
||||
|
||||
awk '
|
||||
r==1 { r=0; if (/>=/){print ">>>="; next}
|
||||
if (/>/) {print ">>>"; next}
|
||||
print ">>" }
|
||||
r==3 { if (/\./){ r=4; next } r=0; print "." }
|
||||
r==4 { if (/\./){ r=0; print "..."; next} print ".\n."}
|
||||
|
||||
# digraphs
|
||||
r==2 { r=0; if (/>/){print "]"; next}
|
||||
if (/:/){print "::"; next}
|
||||
print ":" }
|
||||
r==5 { r=0; if (/:/){print "["; next}
|
||||
if (/%/){print "{"; next}
|
||||
print "<" }
|
||||
r==6 { r=0; if (/>/){print "}"; next}
|
||||
if (/:/){print "#"; next}
|
||||
print "%" }
|
||||
|
||||
/^>>$/ {r=1;next} # java
|
||||
/^:$/ {r=2;next} # c++, java classes, digraph
|
||||
/^\.$/ {r=3;next} # mea culpa - ellipsis
|
||||
/^<$/ {r=5;next} # digraph
|
||||
/^%$/ {r=6;next} # digraph
|
||||
|
||||
{ print $0 }' $*
|
||||
@@ -0,0 +1,111 @@
|
||||
#!/bin/sh
|
||||
|
||||
# unob is a proof-of-concept script.
|
||||
# Prior to tac, scripting the layout of C code was intractable.
|
||||
#
|
||||
# There are uncountably many possible refinements to this script.
|
||||
# Enjoy the madness of getting a perfect layout of C code via
|
||||
# an automated process. Or just enjoy a significant help in
|
||||
# reading obfuscated C code!
|
||||
|
||||
: ${PROG:=./prog} # PROG=tac ./unob.sh prog.c
|
||||
: ${KW:=c11} # KW=ioccc.kw.freq ./unob.sh prog.c
|
||||
: ${DEF:=} # DEF="-DW=\\\"kandr2\\\" -DU=\\\"usage\ string\\\"" ./unob.sh -p prog.c
|
||||
|
||||
# optionally preprocess up to 3 times to handle #ifdef X #define Y
|
||||
# unob prog.c # nonce
|
||||
# unob -p prog.c # once
|
||||
# unob -p -p prog.c # twice
|
||||
# unob -p -p -p prog.c # thrice
|
||||
# unob -p -p -p -p prog.c # yer out
|
||||
|
||||
function pp {
|
||||
cpp2=cat
|
||||
cpp3=cat
|
||||
if [ "x$1" == "x-p" ]; then
|
||||
shift
|
||||
if [ "x$1" == "x-p" ]; then
|
||||
cpp2="cpp -E"
|
||||
shift
|
||||
fi
|
||||
if [ "x$1" == "x-p" ]; then
|
||||
cpp3="cpp -E"
|
||||
shift
|
||||
fi
|
||||
cat $* |
|
||||
sed 's/# *include/##include/' |
|
||||
eval cpp -E "$DEF" |
|
||||
eval $cpp2 |
|
||||
eval $cpp3 |
|
||||
sed 's/^#[^#].*$//' |
|
||||
sed 's/##inc/#inc/'
|
||||
else
|
||||
cat $*
|
||||
fi
|
||||
}
|
||||
|
||||
script='
|
||||
BEGIN {
|
||||
last=nl="\n";
|
||||
f="'$KW'"; while(getline <f > 0) ++kw[$0]; close(f);
|
||||
if (length(kw) == 0) {
|
||||
print "cannot find",f "; check KW environment variable" | "cat 1>&2"
|
||||
exit
|
||||
}
|
||||
}
|
||||
|
||||
function iskw(a) { return a in kw }
|
||||
function indent() { return sprintf("%.*s", n*3, " ") }
|
||||
function newline() { if (!infor && last != nl) printf last=nl }
|
||||
function show(a) {
|
||||
if (len>80 || (len>60 && (last ~ /^;/ || (last ~ /^,/ && paren==0))))
|
||||
printf "%c%s", last=nl, indent() # yes, double indent here
|
||||
if (len>60 && last ~ /^\)/ && a !~ /^\)/ && paren == 0)
|
||||
printf last=nl
|
||||
if (last==nl) { len=0; printf "%s", indent() }
|
||||
|
||||
if (length(a) > 80 && a ~ /\"/) {
|
||||
newline()
|
||||
len = 80
|
||||
max = length(a)
|
||||
for (off=0; off <= max; off += len)
|
||||
printf "%s%s%c%s",
|
||||
substr(a, off, len),
|
||||
(off+len > max) ? "" : "\\",
|
||||
last=nl, indent()
|
||||
len = 0
|
||||
return
|
||||
}
|
||||
|
||||
printf "%s%s", space(), a
|
||||
len += length(a space())
|
||||
last=a
|
||||
}
|
||||
function space() {
|
||||
return iskw(last) ||
|
||||
(last != "." &&
|
||||
last ~ /[A-Za-z0-9_+-\/%^|&\]\)=:<>;]$/ && $0 !~ /[\.:;()\[\],]/) ? " " : ""
|
||||
}
|
||||
|
||||
/^\(/ { ++paren }
|
||||
/^\)/ { --paren }
|
||||
|
||||
/^(if|while|for|return|switch|case|default|union|struct|typedef|#)/ { newline() }
|
||||
|
||||
/^for$/ { newline(); infor=1 }
|
||||
infor && /^;/ { ++infor; show($0 " "); next }
|
||||
infor==1 && /^:/ { ++infor }
|
||||
infor>1 && paren==0 { infor=0 }
|
||||
|
||||
/^\?/ { ++tern; ++n; newline(); show($0 " "); next }
|
||||
tern && /^:/ { newline(); show($0); --tern; --n; next }
|
||||
|
||||
/^#/ { newline(); show($0); newline(); next }
|
||||
/^;/ { show($0); newline(); next }
|
||||
/^{/ { show($0); ++n; newline(); next }
|
||||
/^}/ { --n; newline(); show($0); newline(); next }
|
||||
|
||||
{ show($0) }
|
||||
'
|
||||
|
||||
pp $* | $PROG -t | ./tokenfix | awk "$script" # sed 's/""//g'
|
||||
@@ -0,0 +1,38 @@
|
||||
$ 7th edition Unix source code, c00.c, 1979 cc, cpp.c
|
||||
#define
|
||||
#else
|
||||
#endif
|
||||
#if
|
||||
#ifdef
|
||||
#ifndef
|
||||
#include
|
||||
#line
|
||||
#undef
|
||||
auto
|
||||
break
|
||||
case
|
||||
char
|
||||
continue
|
||||
default
|
||||
do
|
||||
double
|
||||
else
|
||||
enum
|
||||
extern
|
||||
float
|
||||
for
|
||||
goto
|
||||
if
|
||||
int
|
||||
long
|
||||
register
|
||||
return
|
||||
short
|
||||
sizeof
|
||||
static
|
||||
struct
|
||||
switch
|
||||
typedef
|
||||
union
|
||||
unsigned
|
||||
while
|
||||
@@ -0,0 +1,288 @@
|
||||
#!/usr/bin/env make
|
||||
#
|
||||
# 2018 makefile
|
||||
#
|
||||
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
|
||||
# is licensed under:
|
||||
#
|
||||
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
|
||||
#
|
||||
# See: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
|
||||
################
|
||||
# tool locations
|
||||
################
|
||||
#
|
||||
SHELL= /bin/bash
|
||||
CP= cp
|
||||
CPP= cpp
|
||||
GUNZIP= gunzip
|
||||
BUNZIP2= bunzip2
|
||||
GZIP_PROG= gzip
|
||||
BZIP2= bzip2
|
||||
CURL= curl
|
||||
DD= dd
|
||||
LD= ld
|
||||
MAKE= make
|
||||
RM= rm
|
||||
SED= sed
|
||||
TAR= tar
|
||||
TRUE= true
|
||||
MKDIR= mkdir
|
||||
MV= mv
|
||||
TR= tr
|
||||
GREP= grep
|
||||
SORT= sort
|
||||
UNIQ= uniq
|
||||
STRIP= strip
|
||||
|
||||
# Set X11_LIBDIR to the directory where the X11 library resides
|
||||
#
|
||||
#X11_LIBDIR= /usr/X11R6/lib
|
||||
#X11_LIBDIR= /usr/X11/lib
|
||||
X11_LIBDIR= /opt/X11/lib
|
||||
|
||||
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
|
||||
#
|
||||
#X11_INCDIR= /usr/X11R6/include
|
||||
#X11_INCDIR= /usr/X11/include
|
||||
X11_INCDIR= /opt/X11/include
|
||||
|
||||
# Compiler warnings
|
||||
#
|
||||
#CWARN=
|
||||
#CWARN= -Wall
|
||||
#CWARN= -Wall -Wextra
|
||||
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
|
||||
#CWARN= -Wall -Wextra -Weverything
|
||||
#CWARN= -Wall -Wextra -Weverything -pedantic
|
||||
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
|
||||
|
||||
# Silence warnings that ${CWARN} would normally complain about
|
||||
#
|
||||
CSILENCE= -Wno-unused-value -Wno-shift-op-parentheses -Wno-sign-conversion \
|
||||
-Wno-comma -Wno-missing-prototypes -Wno-unused-result -Wno-parentheses
|
||||
#CSILENCE= -Wno-implicit-int
|
||||
|
||||
# compiler standard
|
||||
#
|
||||
#CSTD=
|
||||
#CSTD= -ansi
|
||||
CSTD= -std=c11
|
||||
|
||||
# compiler bit architecture
|
||||
#
|
||||
# Some entries require 32-bitness:
|
||||
# ARCH= -m32
|
||||
#
|
||||
# Some entries require 64-bitness:
|
||||
# ARCH= -m64
|
||||
#
|
||||
# By default we assume nothing:
|
||||
#
|
||||
ARCH=
|
||||
|
||||
# defines that are needed to compile
|
||||
#
|
||||
CDEFINE=
|
||||
#CDEFINE= -DIOCCC=25
|
||||
|
||||
# include files that are needed to compile
|
||||
#
|
||||
CINCLUDE=
|
||||
#CINCLUDE= -include stdlib.h
|
||||
#CINCLUDE= -include stdio.h
|
||||
#CINCLUDE= -include stdlib.h -include stdio.h
|
||||
#CINCLUDE= -I ${X11_INCDIR}
|
||||
|
||||
# optimization
|
||||
#
|
||||
# Most compiles will safely use -O2. Some can use only -O1 or -O.
|
||||
# A few compilers have broken optimizers or this entry make break
|
||||
# under those buggy optimizers and thus you may not want anything.
|
||||
# Reasonable compilers will allow for -O3.
|
||||
#
|
||||
#OPT=
|
||||
#OPT= -O
|
||||
#OPT= -O1
|
||||
#OPT= -O2
|
||||
OPT= -O3
|
||||
|
||||
# default flags for ANSI C compilation
|
||||
#
|
||||
CFLAGS= ${CSTD} ${CWARN} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
|
||||
|
||||
# Libraries needed to build
|
||||
#
|
||||
LIBS=
|
||||
#LIBS= -L ${X11_LIBDIR}
|
||||
|
||||
# ANSI compiler
|
||||
#
|
||||
# Set CC to the name of your ANSI compiler.
|
||||
#
|
||||
# Some entries seem to need gcc. If you have gcc, set
|
||||
# both CC and MAY_NEED_GCC to gcc.
|
||||
#
|
||||
# If you do not have gcc, set CC to the name of your ANSI compiler, and
|
||||
# set MAY_NEED_GCC to either ${CC} (and hope for the best) or to just :
|
||||
# to disable such programs.
|
||||
#
|
||||
CC= cc
|
||||
#CC=clang
|
||||
MAY_NEED_GCC= gcc
|
||||
|
||||
|
||||
##############################
|
||||
# Special flags for this entry
|
||||
##############################
|
||||
#
|
||||
OBJ= prog.o
|
||||
DATA=
|
||||
TARGET= prog
|
||||
#
|
||||
ALT_OBJ=
|
||||
ALT_TARGET= prog.orig
|
||||
|
||||
|
||||
#################
|
||||
# build the entry
|
||||
#################
|
||||
#
|
||||
all: ${TARGET} ${DATA}
|
||||
@${TRUE}
|
||||
|
||||
prog: prog.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
prog.orig: prog.orig.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
# alternative executable
|
||||
#
|
||||
alt: ${ALT_TARGET}
|
||||
@${TRUE}
|
||||
|
||||
# data files
|
||||
#
|
||||
data: ${DATA}
|
||||
@${TRUE}
|
||||
|
||||
|
||||
###############
|
||||
# utility rules
|
||||
###############
|
||||
#
|
||||
everything: all alt
|
||||
|
||||
clean:
|
||||
${RM} -f ${OBJ} ${ALT_OBJ}
|
||||
|
||||
clobber: clean
|
||||
${RM} -f ${TARGET} ${ALT_TARGET}
|
||||
@-if [ -e sandwich ]; then \
|
||||
${RM} -f sandwich; \
|
||||
echo 'ate sandwich'; \
|
||||
fi
|
||||
|
||||
nuke: clobber
|
||||
@${TRUE}
|
||||
|
||||
dist_clean: nuke
|
||||
@${TRUE}
|
||||
|
||||
install:
|
||||
@echo "Surely you are performing, Dr. May!"
|
||||
@${TRUE}
|
||||
|
||||
# backwards compatibility
|
||||
#
|
||||
build: all
|
||||
@${TRUE}
|
||||
|
||||
|
||||
##################
|
||||
# 133t hacker rulz
|
||||
##################
|
||||
#
|
||||
love:
|
||||
@echo 'not war?'
|
||||
@${TRUE}
|
||||
|
||||
haste:
|
||||
$(MAKE) waste
|
||||
@${TRUE}
|
||||
|
||||
waste:
|
||||
@echo 'haste'
|
||||
@${TRUE}
|
||||
|
||||
make:
|
||||
@echo 'Attend a maker faire'
|
||||
@${TRUE}
|
||||
|
||||
easter_egg:
|
||||
@echo you expected to often mis-understand this $${RANDOM} magic
|
||||
@echo chongo '<was here>' "/\\oo/\\"
|
||||
@echo Eggy
|
||||
|
||||
fabricate fashion form frame manufacture produce: make
|
||||
@${TRUE}
|
||||
|
||||
sandwich:
|
||||
@if [ `id -u` -eq 0 ]; then \
|
||||
echo 'Okay.'; \
|
||||
echo $${RANDOM}`date +%s`$${RANDOM} > $@; \
|
||||
else \
|
||||
echo 'What? Make it yourself.'; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
# Understand the history of the Homebrew Computer Club
|
||||
# as well as the West Coast Computer Faire and
|
||||
# you might be confused different. :-)
|
||||
#
|
||||
supernova: nuke
|
||||
@-if [ -r .code_anal ]; then \
|
||||
${RM} -f .code_anal_v6; \
|
||||
else \
|
||||
echo "planet deniers, like some members of the IAU, are so cute when they try to defend their logic"; \
|
||||
fi
|
||||
@echo A $@ helps ${MAKE} the elements that help form planets
|
||||
@${TRUE}
|
||||
|
||||
deep_magic:
|
||||
@-if [ -r .code_anal ]; then \
|
||||
ccode_analysis --deep_magic 3a3fabb90892eeb2f610ae0f74a35a970060665a063ab702bd686c17c4ae07f6 --FNV1a_hash_256_bit "prog"; \
|
||||
else \
|
||||
echo "Wrong! Do it again!"; \
|
||||
sleep 2; \
|
||||
echo "Wrong! Do it again!"; \
|
||||
sleep 2; \
|
||||
echo "Wrong! Do it again!"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
|
||||
magic: deep_magic
|
||||
@-if [ -r .code_anal ]; then \
|
||||
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_256_bit "prog"; \
|
||||
else \
|
||||
echo "If you don't eat yer meat, you can't have any pudding!"; \
|
||||
echo "How can you have any pudding if you don't eat yer meat?!"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
|
||||
# The IOCCC resident astronomer states
|
||||
#
|
||||
charon: supernova
|
||||
@echo $@ is a dwarf planet
|
||||
@echo dwarf is a type of planet
|
||||
@echo $@ is a planet
|
||||
|
||||
pluto: supernova
|
||||
${MAKE} charon
|
||||
@echo $@ is a dwarf planet
|
||||
@echo dwarf is a type of planet
|
||||
@echo $@ is a planet
|
||||
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
|
||||
@@ -0,0 +1,316 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
|
||||
<link rel="stylesheet"
|
||||
type="text/css"
|
||||
href="../hint.css">
|
||||
<title>Most likely to be awarded</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Most likely to be awarded</h1>
|
||||
|
||||
<p>Marcin Ciura <a href="mailto:mciura@gmail.com">mciura@gmail.com</a><br>
|
||||
Twitter: @mciura</p>
|
||||
|
||||
<h2>Judges' comments:</h2>
|
||||
|
||||
<h3>To use:</h3>
|
||||
|
||||
<pre><code>make
|
||||
|
||||
./prog < text
|
||||
</code></pre>
|
||||
|
||||
<h3>Try:</h3>
|
||||
|
||||
<pre><code>./prog < Makefile
|
||||
./prog < hint.text
|
||||
</code></pre>
|
||||
|
||||
<h3>Selected Judges Remarks:</h3>
|
||||
|
||||
<p>This text was processed by prog. You may get confused.
|
||||
We’re not really sure: prog.c wasn’t commented.
|
||||
Who has been thoroughly puzzled by prog? Also how obfuscated is prog?
|
||||
Having been written in C, how large of a vocabulary has it?</p>
|
||||
|
||||
<h2>Author’s comments:</h2>
|
||||
|
||||
<h1>The Program</h1>
|
||||
|
||||
<p>“The Elements of Style” by prof. William Strunk, Jr. and E. B. White
|
||||
is well known for its dislike of the passive voice. Direct, vigorous,
|
||||
active constructions were instead recommended by the authors.
|
||||
The development of this program has been driven by this tenet.</p>
|
||||
|
||||
<p>Only passive sentences from the standard input are output. The offending
|
||||
part(s) of each sentence will be highlighted. Several kinds of passive
|
||||
constructions are recognized:</p>
|
||||
|
||||
<ul>
|
||||
<li>Plain passive voice.
|
||||
Foo was bazzed by bar.</li>
|
||||
<li>Passive voice with “get”.
|
||||
I got almost quuxed.</li>
|
||||
<li>Contractions.
|
||||
I’m not really quuxed: foo wasn’t bazzed.</li>
|
||||
<li>Questions.
|
||||
Who has been quuxed? Was foo indeed bazzed? How was it bazzed?</li>
|
||||
<li>Clause-initial inversion.
|
||||
Also bazzed is bar.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>Sentences are never broken by periods that follow abbreviations and
|
||||
initials. Both regular and irregular past participles are properly
|
||||
dealt with. Note that some words are red herrings: even though their
|
||||
ending is -ed, they are not past participles.</p>
|
||||
|
||||
<h1>The Big String</h1>
|
||||
|
||||
<p>Here is the purpose of every byte inside the <strong><code>c[]</code></strong> string:</p>
|
||||
|
||||
<ul>
|
||||
<li>0-9: highlighting passive constructions in the output;</li>
|
||||
<li>10-50: classifying characters - called by <strong><code>V(4)</code></strong>;</li>
|
||||
<li>52: outputting the newline character;</li>
|
||||
<li>51-187: tokenizing text and detecting passive constructions - two
|
||||
type A state machines, called by <strong><code>V(2)</code></strong> and <strong><code>V(3)</code></strong>;</li>
|
||||
<li>186-2786: determining word categories (past participles, present
|
||||
simple and past simple forms of “to be”, other forms of “to be”,
|
||||
adverbs, wh-words, and other words) and recognizing abbreviations -
|
||||
two type B state machines, called by <strong><code>V(808)</code></strong> and <strong><code>V(205)</code></strong>.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h1>The State Machines</h1>
|
||||
|
||||
<p>I heard you don’t like state machines so I put a state machine in your
|
||||
state machine so you can reject this entry while you reject this entry.</p>
|
||||
|
||||
<p>Both types of state machines in the program are Mealy machines: we can
|
||||
think of their transitions as triples (<strong><code>transition_label</code></strong>,
|
||||
<strong><code>next_state</code></strong>, <strong><code>output</code></strong>).</p>
|
||||
|
||||
<h2>Type A</h2>
|
||||
|
||||
<p>A state of type A state machine consists of eight transitions whose
|
||||
representations occupy consecutive bytes. The byte
|
||||
<strong><code>c[3 + 8*state + transition_label]</code></strong> contains
|
||||
<strong><code>(unsigned char)(30 + 5*next_state + output)</code></strong>.</p>
|
||||
|
||||
<p>The <code>transition_label</code> is either one of character classes:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong><code>nil</code></strong> = 0,</li>
|
||||
<li><strong><code>space</code></strong> = 1,</li>
|
||||
<li><strong><code>new_line</code></strong> = 2,</li>
|
||||
<li><strong><code>uppercase</code></strong> = 3,</li>
|
||||
<li><strong><code>lowercase</code></strong> = 4,</li>
|
||||
<li><strong><code>period</code></strong> = 5,</li>
|
||||
<li><strong><code>bang_question</code></strong> = 6,</li>
|
||||
<li><strong><code>punctuation</code></strong> = 7,</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>or one of word classes:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong><code>adverb</code></strong> = 0,</li>
|
||||
<li><strong><code>other</code></strong> = 2,</li>
|
||||
<li><strong><code>past_participle</code></strong> = 3,</li>
|
||||
<li><strong><code>to_be</code></strong> = 4,</li>
|
||||
<li><strong><code>are_were</code></strong> = 5,</li>
|
||||
<li><strong><code>wh_word</code></strong> = 6 (cf. the <strong><code>output</code></strong> of type B state machines).</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>The <strong><code>output</code></strong> is either one of:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong><code>end_of_text</code></strong> = 0,</li>
|
||||
<li><strong><code>sentence_start</code></strong> = 1,</li>
|
||||
<li><strong><code>sentence_end</code></strong> = 2,</li>
|
||||
<li><strong><code>token_end</code></strong> = 3,</li>
|
||||
<li><strong><code>ignore</code></strong> = 4,</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>or one of</p>
|
||||
|
||||
<ul>
|
||||
<li><strong><code>passive_construction_start</code></strong> = 1,</li>
|
||||
<li><strong><code>ignore</code></strong> = 2,</li>
|
||||
<li><strong><code>passive_construction_end</code></strong> = 3.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>Type A state machines run continuously. Their state is kept in
|
||||
<strong><code>k[2]</code></strong> and <strong><code>k[3]</code></strong>.</p>
|
||||
|
||||
<p>Below are sample steps of scanning a sequence of characters with
|
||||
classes <strong><code>uppercase</code></strong>, <strong><code>lowercase</code></strong>, <strong><code>period</code></strong>, <strong><code>space</code></strong>,
|
||||
and <strong><code>uppercase</code></strong>.</p>
|
||||
|
||||
<ul>
|
||||
<li><strong><code>state</code></strong> = 7, <strong><code>transition_label</code></strong> = 3 (<strong><code>uppercase</code></strong>), <strong><code>output</code></strong> = <strong><code>sentence_start</code></strong></li>
|
||||
<li><strong><code>state</code></strong> = 14, <strong><code>transition_label</code></strong> = 4 (<strong><code>lowercase</code></strong>), <strong><code>output</code></strong> = <strong><code>ignore</code></strong></li>
|
||||
<li><strong><code>state</code></strong> = 15, <strong><code>transition_label</code></strong> = 5 (<strong><code>period</code></strong>), <strong><code>output</code></strong> = <strong><code>token_end</code></strong></li>
|
||||
<li><strong><code>state</code></strong> = 13, <strong><code>transition_label</code></strong> = 1 (<strong><code>space</code></strong>), <strong><code>output</code></strong> = <strong><code>token_end</code></strong></li>
|
||||
<li><strong><code>state</code></strong> = 18, <strong><code>transition_label</code></strong> = 3 (<strong><code>uppercase</code></strong>), <strong><code>output</code></strong> = <strong><code>sentence_end</code></strong></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>And here are sample steps of scanning tokens with classes <strong><code>to_be</code></strong>,
|
||||
<strong><code>adverb</code></strong>, <strong><code>past_participle</code></strong>.</p>
|
||||
|
||||
<ul>
|
||||
<li><strong><code>state</code></strong> = 8, <strong><code>transition_label</code></strong> = 4 (<strong><code>to_be</code></strong>), <strong><code>output</code></strong> = <strong><code>passive_construction_start</code></strong></li>
|
||||
<li><strong><code>state</code></strong> = 22, <strong><code>transition_label</code></strong> = 0 (<strong><code>adverb</code></strong>), <strong><code>output</code></strong> = <strong><code>ignore</code></strong></li>
|
||||
<li><strong><code>state</code></strong> = 22, <strong><code>transition_label</code></strong> = 3 (<strong><code>past_participle</code></strong>), <strong><code>output</code></strong> = <strong><code>passive_construction_end</code></strong></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Type B</h2>
|
||||
|
||||
<p>Type B state machines are built by a variant of the algorithm described
|
||||
in the paper
|
||||
<em><a href="http://sun.aei.polsl.pl/~mciura/publikacje/lexicon.pdf">How to squeeze a lexicon</a></em>.
|
||||
Their states are represented as interlaced sparse arrays of transitions.</p>
|
||||
|
||||
<p>The <strong><code>transition_label</code></strong> is one of:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong><code>word_start</code></strong> = 0,</li>
|
||||
<li><strong><code>period_or_apostrophe</code></strong> = 1,</li>
|
||||
<li><strong><code>a_z_letter</code></strong> = 2..27.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>The <code>output</code> is either one of word classes:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong><code>adverb</code></strong> = 0,</li>
|
||||
<li><strong><code>ignore</code></strong> = 1,</li>
|
||||
<li><strong><code>other</code></strong> = 2,</li>
|
||||
<li><strong><code>past_participle</code></strong> = 3,</li>
|
||||
<li><strong><code>to_be</code></strong> = 4,</li>
|
||||
<li><strong><code>are_were</code></strong> = 5,</li>
|
||||
<li><strong><code>wh_word</code></strong> = 6,</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>or</p>
|
||||
|
||||
<ul>
|
||||
<li><strong><code>ignore</code></strong> = 1,</li>
|
||||
<li><strong><code>abbreviation</code></strong> = 2.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>The byte <strong><code>c[186 + (state + transition_label)] = (unsigned char)(2 + transition_label + 28 * output)</code></strong>.</p>
|
||||
|
||||
<p>The byte <strong><code>c[836 + 2*(state + transition_label)] =</code></strong></p>
|
||||
|
||||
<ul>
|
||||
<li><strong><code>' '</code></strong> when <strong><code>next_state / 376 == 0</code></strong>,</li>
|
||||
<li><strong><code>';'</code></strong> when <strong><code>next_state / 376 == 1</code></strong>.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>The byte <strong><code>c[837 + 2*(state + transition_label)] =</code></strong></p>
|
||||
|
||||
<ul>
|
||||
<li><strong><code>' '</code></strong> when <strong><code>next_state / 94 % 4 == 0</code></strong>,</li>
|
||||
<li><strong><code>';'</code></strong> when <strong><code>next_state / 94 % 4 == 1</code></strong>,</li>
|
||||
<li><strong><code>'{'</code></strong> when <strong><code>next_state / 94 % 4 == 2</code></strong>,</li>
|
||||
<li><strong><code>'}'</code></strong> when <strong><code>next_state / 94 % 4 == 3</code></strong>.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>The byte <strong><code>c[2136 + (state + transition_label)] = (unsigned char)(32 + next_state % 94)</code></strong>.</p>
|
||||
|
||||
<p>A type B state machine starts in a given <strong><code>state</code></strong> with <strong><code>output</code></strong>
|
||||
set to <strong><code>ignore</code></strong>. It scans a word backwards, converting character by
|
||||
character to <strong><code>transition_label</code></strong>. When it meets <strong><code>word_start</code></strong>, it
|
||||
returns, leaving the most recently stored <strong><code>output</code></strong> in <strong><code>v</code></strong>.
|
||||
It also returns when
|
||||
<strong><code>c[186 + (state + transition_label)] != (unsigned char)(2 + transition_label + 28 * output)</code></strong>,
|
||||
i.e. when the <strong><code>transition_label</code></strong> in the byte mismatches the
|
||||
<strong><code>transition_label</code></strong> used to compute the index. Otherwise, if the
|
||||
<strong><code>output</code></strong> in this byte differs from <strong><code>ignore</code></strong>, the state machine
|
||||
stores it in <strong><code>v</code></strong>. Regardless of the value of the <strong><code>output</code></strong>,
|
||||
it also assigns <strong><code>next_state</code></strong> to <strong><code>state</code></strong> and proceeds to scan
|
||||
the previous character. The state machine that determines the word
|
||||
class is set up so that it never returns <strong><code>ignore</code></strong>.</p>
|
||||
|
||||
<p>Below are sample steps of scanning the word “chiefly”.</p>
|
||||
|
||||
<ul>
|
||||
<li><strong><code>state</code></strong> = 623, <strong><code>transition_label</code></strong> = 26 (‘y’), <strong><code>output</code></strong> = <strong><code>other</code></strong></li>
|
||||
<li><strong><code>state</code></strong> = 602, <strong><code>transition_label</code></strong> = 13 (‘l’), <strong><code>output</code></strong> = <strong><code>adverb</code></strong></li>
|
||||
<li><strong><code>state</code></strong> = 594, <strong><code>transition_label</code></strong> = 7 (‘f’), <strong><code>output</code></strong> = <strong><code>other</code></strong></li>
|
||||
<li><strong><code>state</code></strong> = 549, <strong><code>transition_label</code></strong> = 6 (‘e’), <strong><code>output</code></strong> = <strong><code>ignore</code></strong></li>
|
||||
<li><strong><code>state</code></strong> = 543, <strong><code>transition_label</code></strong> = 10 (‘i’), <strong><code>output</code></strong> = <strong><code>adverb</code></strong></li>
|
||||
<li><strong><code>state</code></strong> = 0, <strong><code>transition_label</code></strong> = 9 (‘h’) mismatches the value stored
|
||||
in the byte. Return <strong><code>adverb</code></strong>.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>And here are sample steps of scanning the string “i.e.”:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong><code>state</code></strong> = 19, <strong><code>transition_label</code></strong> = 1 (‘.’), <strong><code>output</code></strong> = <strong><code>ignore</code></strong></li>
|
||||
<li><strong><code>state</code></strong> = 24, <strong><code>transition_label</code></strong> = 6 (‘e’), <strong><code>output</code></strong> = <strong><code>ignore</code></strong></li>
|
||||
<li><strong><code>state</code></strong> = 3, <strong><code>transition_label</code></strong> = 1 (‘.’), <strong><code>output</code></strong> = <strong><code>ignore</code></strong></li>
|
||||
<li><strong><code>state</code></strong> = 2, <strong><code>transition_label</code></strong> = 10 (‘i’), <strong><code>output</code></strong> = <strong><code>ignore</code></strong></li>
|
||||
<li><strong><code>state</code></strong> = 1, <strong><code>transition_label</code></strong> = 0 (‘\0’), <strong><code>output</code></strong> = <strong><code>abbreviation</code></strong>.
|
||||
Return <strong><code>abbreviation</code></strong>.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h1>Remarks</h1>
|
||||
|
||||
<p>The judges found a bug in the handling of contractions: <strong><code>prog.orig.c</code></strong>
|
||||
outputs “foo wasn'<strong>[t bazzed]</strong>”. I fixed the bug in <strong><code>prog.c</code></strong>, making
|
||||
it output “foo <strong>[wasn’t bazzed]</strong>” instead, and took the liberty to merge
|
||||
one statement into a <strong><code>for</code></strong> loop inside its <strong><code>main()</code></strong> function.</p>
|
||||
|
||||
<p>The program uses a 9,437,187-byte buffer so it probably will not run
|
||||
on 16-bit and smaller machines without changing the size of array <strong><code>C[]</code></strong>
|
||||
and the expression <strong><code>9<<20</code></strong> inside the call to <strong><code>read()</code></strong>.</p>
|
||||
|
||||
<p>I have tested it on:</p>
|
||||
|
||||
<ul>
|
||||
<li>Linux with gcc version 5.4.0 20160609,</li>
|
||||
<li>Linux with clang version 3.4-1ubuntu3,</li>
|
||||
<li>OS/X with Apple LLVM version 6.0 (clang-600.0.57).</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>For a clean compile under c89 and c90, add <strong><code>-Woverlength-strings</code></strong>
|
||||
to <strong><code>CSILENCE</code></strong>.</p>
|
||||
|
||||
<hr />
|
||||
|
||||
<!--
|
||||
(c) Copyright 1984-2018, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
|
||||
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
|
||||
|
||||
[judges]: http://www.ioccc.org/judges.html
|
||||
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
-->
|
||||
|
||||
<TABLE><TR>
|
||||
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
|
||||
<TD><P>© Copyright 1984-2018,
|
||||
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
|
||||
- All rights reserved<BR>
|
||||
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
|
||||
<TD> <!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
|
||||
</TR></TABLE>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,249 @@
|
||||
# Most likely to be awarded
|
||||
|
||||
Marcin Ciura <mciura@gmail.com>
|
||||
Twitter: @mciura
|
||||
|
||||
|
||||
## Judges' comments:
|
||||
### To use:
|
||||
|
||||
make
|
||||
|
||||
./prog < text
|
||||
|
||||
### Try:
|
||||
|
||||
./prog < Makefile
|
||||
./prog < hint.text
|
||||
|
||||
### Selected Judges Remarks:
|
||||
|
||||
This text was processed by prog. You may get confused.
|
||||
We're not really sure: prog.c wasn't commented.
|
||||
Who has been thoroughly puzzled by prog? Also how obfuscated is prog?
|
||||
Having been written in C, how large of a vocabulary has it?
|
||||
|
||||
|
||||
## Author's comments:
|
||||
The Program
|
||||
===========
|
||||
|
||||
"The Elements of Style" by prof. William Strunk, Jr. and E. B. White
|
||||
is well known for its dislike of the passive voice. Direct, vigorous,
|
||||
active constructions were instead recommended by the authors.
|
||||
The development of this program has been driven by this tenet.
|
||||
|
||||
Only passive sentences from the standard input are output. The offending
|
||||
part(s) of each sentence will be highlighted. Several kinds of passive
|
||||
constructions are recognized:
|
||||
|
||||
* Plain passive voice.
|
||||
Foo was bazzed by bar.
|
||||
* Passive voice with "get".
|
||||
I got almost quuxed.
|
||||
* Contractions.
|
||||
I'm not really quuxed: foo wasn't bazzed.
|
||||
* Questions.
|
||||
Who has been quuxed? Was foo indeed bazzed? How was it bazzed?
|
||||
* Clause-initial inversion.
|
||||
Also bazzed is bar.
|
||||
|
||||
Sentences are never broken by periods that follow abbreviations and
|
||||
initials. Both regular and irregular past participles are properly
|
||||
dealt with. Note that some words are red herrings: even though their
|
||||
ending is -ed, they are not past participles.
|
||||
|
||||
The Big String
|
||||
==============
|
||||
|
||||
Here is the purpose of every byte inside the **`c[]`** string:
|
||||
|
||||
* 0-9: highlighting passive constructions in the output;
|
||||
* 10-50: classifying characters - called by **`V(4)`**;
|
||||
* 52: outputting the newline character;
|
||||
* 51-187: tokenizing text and detecting passive constructions - two
|
||||
type A state machines, called by **`V(2)`** and **`V(3)`**;
|
||||
* 186-2786: determining word categories (past participles, present
|
||||
simple and past simple forms of "to be", other forms of "to be",
|
||||
adverbs, wh-words, and other words) and recognizing abbreviations -
|
||||
two type B state machines, called by **`V(808)`** and **`V(205)`**.
|
||||
|
||||
The State Machines
|
||||
==================
|
||||
|
||||
I heard you don't like state machines so I put a state machine in your
|
||||
state machine so you can reject this entry while you reject this entry.
|
||||
|
||||
Both types of state machines in the program are Mealy machines: we can
|
||||
think of their transitions as triples (**`transition_label`**,
|
||||
**`next_state`**, **`output`**).
|
||||
|
||||
Type A
|
||||
------
|
||||
|
||||
A state of type A state machine consists of eight transitions whose
|
||||
representations occupy consecutive bytes. The byte
|
||||
**`c[3 + 8*state + transition_label]`** contains
|
||||
**`(unsigned char)(30 + 5*next_state + output)`**.
|
||||
|
||||
The `transition_label` is either one of character classes:
|
||||
|
||||
* **`nil`** = 0,
|
||||
* **`space`** = 1,
|
||||
* **`new_line`** = 2,
|
||||
* **`uppercase`** = 3,
|
||||
* **`lowercase`** = 4,
|
||||
* **`period`** = 5,
|
||||
* **`bang_question`** = 6,
|
||||
* **`punctuation`** = 7,
|
||||
|
||||
or one of word classes:
|
||||
|
||||
* **`adverb`** = 0,
|
||||
* **`other`** = 2,
|
||||
* **`past_participle`** = 3,
|
||||
* **`to_be`** = 4,
|
||||
* **`are_were`** = 5,
|
||||
* **`wh_word`** = 6 (cf. the **`output`** of type B state machines).
|
||||
|
||||
The **`output`** is either one of:
|
||||
|
||||
* **`end_of_text`** = 0,
|
||||
* **`sentence_start`** = 1,
|
||||
* **`sentence_end`** = 2,
|
||||
* **`token_end`** = 3,
|
||||
* **`ignore`** = 4,
|
||||
|
||||
or one of
|
||||
|
||||
* **`passive_construction_start`** = 1,
|
||||
* **`ignore`** = 2,
|
||||
* **`passive_construction_end`** = 3.
|
||||
|
||||
Type A state machines run continuously. Their state is kept in
|
||||
**`k[2]`** and **`k[3]`**.
|
||||
|
||||
Below are sample steps of scanning a sequence of characters with
|
||||
classes **`uppercase`**, **`lowercase`**, **`period`**, **`space`**,
|
||||
and **`uppercase`**.
|
||||
|
||||
* **`state`** = 7, **`transition_label`** = 3 (**`uppercase`**), **`output`** = **`sentence_start`**
|
||||
* **`state`** = 14, **`transition_label`** = 4 (**`lowercase`**), **`output`** = **`ignore`**
|
||||
* **`state`** = 15, **`transition_label`** = 5 (**`period`**), **`output`** = **`token_end`**
|
||||
* **`state`** = 13, **`transition_label`** = 1 (**`space`**), **`output`** = **`token_end`**
|
||||
* **`state`** = 18, **`transition_label`** = 3 (**`uppercase`**), **`output`** = **`sentence_end`**
|
||||
|
||||
And here are sample steps of scanning tokens with classes **`to_be`**,
|
||||
**`adverb`**, **`past_participle`**.
|
||||
|
||||
* **`state`** = 8, **`transition_label`** = 4 (**`to_be`**), **`output`** = **`passive_construction_start`**
|
||||
* **`state`** = 22, **`transition_label`** = 0 (**`adverb`**), **`output`** = **`ignore`**
|
||||
* **`state`** = 22, **`transition_label`** = 3 (**`past_participle`**), **`output`** = **`passive_construction_end`**
|
||||
|
||||
Type B
|
||||
------
|
||||
|
||||
Type B state machines are built by a variant of the algorithm described
|
||||
in the paper
|
||||
*[How to squeeze a lexicon](http://sun.aei.polsl.pl/~mciura/publikacje/lexicon.pdf)*.
|
||||
Their states are represented as interlaced sparse arrays of transitions.
|
||||
|
||||
The **`transition_label`** is one of:
|
||||
|
||||
* **`word_start`** = 0,
|
||||
* **`period_or_apostrophe`** = 1,
|
||||
* **`a_z_letter`** = 2..27.
|
||||
|
||||
The `output` is either one of word classes:
|
||||
|
||||
* **`adverb`** = 0,
|
||||
* **`ignore`** = 1,
|
||||
* **`other`** = 2,
|
||||
* **`past_participle`** = 3,
|
||||
* **`to_be`** = 4,
|
||||
* **`are_were`** = 5,
|
||||
* **`wh_word`** = 6,
|
||||
|
||||
or
|
||||
|
||||
* **`ignore`** = 1,
|
||||
* **`abbreviation`** = 2.
|
||||
|
||||
The byte **`c[186 + (state + transition_label)] = (unsigned char)(2 + transition_label + 28 * output)`**.
|
||||
|
||||
The byte **`c[836 + 2*(state + transition_label)] =`**
|
||||
|
||||
* **`' '`** when **`next_state / 376 == 0`**,
|
||||
* **`';'`** when **`next_state / 376 == 1`**.
|
||||
|
||||
The byte **`c[837 + 2*(state + transition_label)] =`**
|
||||
|
||||
* **`' '`** when **`next_state / 94 % 4 == 0`**,
|
||||
* **`';'`** when **`next_state / 94 % 4 == 1`**,
|
||||
* **`'{'`** when **`next_state / 94 % 4 == 2`**,
|
||||
* **`'}'`** when **`next_state / 94 % 4 == 3`**.
|
||||
|
||||
The byte **`c[2136 + (state + transition_label)] = (unsigned char)(32 + next_state % 94)`**.
|
||||
|
||||
A type B state machine starts in a given **`state`** with **`output`**
|
||||
set to **`ignore`**. It scans a word backwards, converting character by
|
||||
character to **`transition_label`**. When it meets **`word_start`**, it
|
||||
returns, leaving the most recently stored **`output`** in **`v`**.
|
||||
It also returns when
|
||||
**`c[186 + (state + transition_label)] != (unsigned char)(2 + transition_label + 28 * output)`**,
|
||||
i.e. when the **`transition_label`** in the byte mismatches the
|
||||
**`transition_label`** used to compute the index. Otherwise, if the
|
||||
**`output`** in this byte differs from **`ignore`**, the state machine
|
||||
stores it in **`v`**. Regardless of the value of the **`output`**,
|
||||
it also assigns **`next_state`** to **`state`** and proceeds to scan
|
||||
the previous character. The state machine that determines the word
|
||||
class is set up so that it never returns **`ignore`**.
|
||||
|
||||
Below are sample steps of scanning the word "chiefly".
|
||||
|
||||
* **`state`** = 623, **`transition_label`** = 26 ('y'), **`output`** = **`other`**
|
||||
* **`state`** = 602, **`transition_label`** = 13 ('l'), **`output`** = **`adverb`**
|
||||
* **`state`** = 594, **`transition_label`** = 7 ('f'), **`output`** = **`other`**
|
||||
* **`state`** = 549, **`transition_label`** = 6 ('e'), **`output`** = **`ignore`**
|
||||
* **`state`** = 543, **`transition_label`** = 10 ('i'), **`output`** = **`adverb`**
|
||||
* **`state`** = 0, **`transition_label`** = 9 ('h') mismatches the value stored
|
||||
in the byte. Return **`adverb`**.
|
||||
|
||||
And here are sample steps of scanning the string "i.e.":
|
||||
|
||||
* **`state`** = 19, **`transition_label`** = 1 ('.'), **`output`** = **`ignore`**
|
||||
* **`state`** = 24, **`transition_label`** = 6 ('e'), **`output`** = **`ignore`**
|
||||
* **`state`** = 3, **`transition_label`** = 1 ('.'), **`output`** = **`ignore`**
|
||||
* **`state`** = 2, **`transition_label`** = 10 ('i'), **`output`** = **`ignore`**
|
||||
* **`state`** = 1, **`transition_label`** = 0 ('\0'), **`output`** = **`abbreviation`**.
|
||||
Return **`abbreviation`**.
|
||||
|
||||
Remarks
|
||||
=======
|
||||
|
||||
The judges found a bug in the handling of contractions: **`prog.orig.c`**
|
||||
outputs "foo wasn'**[t bazzed]**". I fixed the bug in **`prog.c`**, making
|
||||
it output "foo **[wasn't bazzed]**" instead, and took the liberty to merge
|
||||
one statement into a **`for`** loop inside its **`main()`** function.
|
||||
|
||||
The program uses a 9,437,187-byte buffer so it probably will not run
|
||||
on 16-bit and smaller machines without changing the size of array **`C[]`**
|
||||
and the expression **`9<<20`** inside the call to **`read()`**.
|
||||
|
||||
I have tested it on:
|
||||
|
||||
* Linux with gcc version 5.4.0 20160609,
|
||||
* Linux with clang version 3.4-1ubuntu3,
|
||||
* OS/X with Apple LLVM version 6.0 (clang-600.0.57).
|
||||
|
||||
For a clean compile under c89 and c90, add **`-Woverlength-strings`**
|
||||
to **`CSILENCE`**.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
<!--
|
||||
(c) Copyright 1984-2018, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
|
||||
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
|
||||
|
||||
[judges]: http://www.ioccc.org/judges.html
|
||||
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
-->
|
||||
@@ -0,0 +1,126 @@
|
||||
#include<unistd.h>
|
||||
#define W ),write(1,
|
||||
static unsigned char c[]=
|
||||
"]\33[0m\33[7m[&&'% $ # ! ########## \" # !& \n oo 6''GLB=.* eoj* 5SXINE@199999999777777775]bNNE@@5]bNNE@E5SXOO0?05SXOOD?06TYJOE@16Y%JOE@16^c%O%%%6c%%O%%%f !! k k! p !oo :;;\37;;;;;\37;($\"%$##(\37(/1$1.,,,$%&/1rs!58&30123$$-O@2=\2?(2-'VZ$3:'i/3+ O#&B2%1,: 2=' (1J!1AC) @:,+_M1H/:J I\"?.Ak'.c2G$gj!j.@O&'(P +,jk/Y1$3%56.8 Y1. .4, W +nd\\rs1( ++(-.331i\".>.-[!.^'.\00281\216\217\252\253's 6\b.$\252\2534''0(\0226 6!'# +[\34.-\"+,-\"(4123Z5_]3-+46(44ij3.jneij41$3+%16s c` 3!#6.(n _\".] R+'4.jjkf`'\\..Y.(' i1 f%nG. $=i$#$ `'3V*+.b2&.!23+5.'n9\\\2ij&1j_3k^_n/+i_ij cd-$$11j(%3&'..\n!1$.4 623$ \2$' rs6${$\"\25($3-5.3''' $2.'\b(1( -.\0253,63''6 8\241+ 6\37 $-$I(P(($\252\253cZ/2\b'i4j3$86&4 j!k-J &1N]'+,fcY-ej/$fgl8 n4!$cd (^'$4+bc-g -2($.iZn$%Yc\20 4+Z,)$.'.\0071 1.'g1\37 4-$$%1'(D=+,-./+12 4,,7\f$ 1:3'+,?.='= #.%$)K!(123&(J3:4$J4 $52#(<! ,$AK;( !+# ./'1 \17 1\252\253<=>?@ABCDEFGHIJKLMNOPQRSTU ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; { { ; ; ; { ; ; { { ; ; { { { { { ; ; ; { { { { ; { { ; { { ; { { ; ; { { { ; { { { ; ; { { { ; ; { { { { { { { { { } ; { { { ; } } { { } } { { { { { } } { } } } } ; } } } { ; } } ; } } } } } } } ; } } } } } } } } } { } ; ; } } } }; ; ; } } { }; } }; ; ; ; ; ; ; ; ; ; ;; ; }; ; ; } ;; ; ; ; ; ; ; ; ; ;; ; ; ; ; {; ; ; ; ; ; } ; } ; ;;; } ; ; ; ; ;;; ; } };; } ; ;;; ;; ;;;; ;;; ;;;; ;; { ;;; ; ;; ; ; ; ;;; ; ;;; ;;;;;;;;; ;;;;;; ; ;; ;; ;; ;; ; ;; ;; ;; ;{ ;;;{ ;{ ;; ;{;;;; ;;;; {;{;; ;;;{ ;;; ;{ ;{ ; { { { { { { { } } ; ; ;; ;; ;{ \" ' !!!!$!!(8I!!,%&!!!#*)2. C!!CH'-/0@B+ L UJM< N4 [Q?DX[ Jc !ad' in fit` !w !V mL r L p z s Vv e x _ vb !VY o\\q j (x [|!E\"&@+10y?UJ W$ 6 [OPUDXAF]US Zj lac[q $n We y |) #w zk)Us |$ `Ub,5 )F8V_h;#4\"u% 0 $<CJUIJG $X < @67$X)Z$ | YUC])ZZ h dO m s<Ky < ^wUW x#${ oU@r Z 2 Ufg<$T| njv U+/[u(>1C$ \" . I4 U $+ Al 6M3UQ 8Uv+kV5 U;pBKU`P)jX Xe Cw }\" ++{UyZo$lC}*C,& .#C>'+ 52|4/B)7+ +|@1--9M6 L ||Q =P R ? )GH\\Vk[ [ f ICfB [[[!r 6 b$! UI!z[p |sC$)x[ U$IU[e+B XU >zU 0U-?$O @Yx:) 4EZCU/lUAco 'q.*9[}G_HLBI j(! m!!t , l x!q!|! ! !!!!! ! q$ ( $U! < c 'do nN)\"S w4k} = 0 A Y1+-9 =Scaf !OZ B F "
|
||||
|
||||
,C[3^9
|
||||
<<20],*k[
|
||||
4]={
|
||||
1+C,
|
||||
0,59
|
||||
+c}
|
||||
,**K
|
||||
,*l,*L,*
|
||||
o,O,p,
|
||||
|
||||
P,s,S=1,v=4 ;
|
||||
int V(int w){
|
||||
return
|
||||
1<w
|
||||
?3<
|
||||
w?4
|
||||
<w?
|
||||
5<w
|
||||
?6<
|
||||
|
||||
w?O=(O=*
|
||||
--l,O/64-
|
||||
1?1 &129
|
||||
>>O -39
|
||||
:27>(O%=
|
||||
32)&&0<O
|
||||
?1+ O:0
|
||||
),w +=O
|
||||
,O- (c[
|
||||
|
||||
|
||||
w]- 2)%
|
||||
28|| (1-
|
||||
(O= (c[
|
||||
w]- 2)/
|
||||
28) ?v=
|
||||
O:0 ,V(
|
||||
154+ 1950
|
||||
[w+c]+94*
|
||||
(464[w+
|
||||
|
||||
c+w ]/3
|
||||
%5+ 465
|
||||
[w+c +w]
|
||||
%26/7 )))
|
||||
:!( 3- v?2
|
||||
>v? L=1[k
|
||||
]=* k,3[
|
||||
k]= 67+
|
||||
c:3 >v?
|
||||
|
||||
V(0 ),p
|
||||
?(0 W L,
|
||||
*k- L W
|
||||
52+ c,
|
||||
1),p=
|
||||
0:0 ,L
|
||||
:L: (v=
|
||||
1,l =*k
|
||||
,V( 205
|
||||
|
||||
|
||||
),1-v
|
||||
?2 [k]
|
||||
=75 +c:
|
||||
o,V(
|
||||
3), v%3 ?2>
|
||||
v?V (1), o=
|
||||
1[k ]:L:(
|
||||
p=(P=1 W L,o
|
||||
-L W c +s,S
|
||||
|
||||
W o ,*k
|
||||
- o W c
|
||||
,S) ,L=
|
||||
*k) , 1[k
|
||||
]=* k )):
|
||||
(l= *k, V (
|
||||
808 ),v ):(
|
||||
v=* ++*k
|
||||
,39 -c[
|
||||
|
||||
v>> 7 ?
|
||||
15: 1-v
|
||||
/32 ?10
|
||||
-v?(312-v %
|
||||
32)/26+v/32
|
||||
*2: 13:
|
||||
82- v])
|
||||
:!( w[k
|
||||
]+= V(2
|
||||
|
||||
+w)
|
||||
,v=
|
||||
*w[
|
||||
k]%
|
||||
5,w
|
||||
[k]
|
||||
=*w
|
||||
[k]
|
||||
/5*
|
||||
|
||||
8+3+c):(K=k+w
|
||||
,33>*(*K-=!w)
|
||||
?*K
|
||||
+=w
|
||||
,V(
|
||||
w):
|
||||
!(*
|
||||
K+=
|
||||
!w)
|
||||
|
||||
);}int main()
|
||||
{ read(s,2+C,
|
||||
9<<
|
||||
20);for(s
|
||||
=isatty(S
|
||||
)?S
|
||||
=5:
|
||||
9;v; V(2))V(6
|
||||
); return P;}
|
||||
@@ -0,0 +1,126 @@
|
||||
#include<unistd.h>
|
||||
#define W ),write(1,
|
||||
static unsigned char c[]=
|
||||
"]\33[0m\33[7m[&&'% $ # ! ########## \" !& \n oo 6''GLB=.* eoj* 5SXINE@199999999777777775]bNNE@@5]bNNE@E5SXOO0?05SXOOD?06TYJOE@16Y%JOE@16^c%O%%%6c%%O%%%f !! k k! p !oo :;;\37;;;;;\37;($\"%$##(\37(/1$1.,,,$%&/1rs!58&30123$$-O@2=\2?(2-'VZ$3:'i/3+ O#&B2%1,: 2=' (1J!1AC) @:,+_M1H/:J I\"?.Ak'.c2G$gj!j.@O&'(P +,jk/Y1$3%56.8 Y1. .4, W +nd\\rs1( ++(-.331i\".>.-[!.^'.\00281\216\217\252\253's 6\b.$\252\2534''0(\0226 6!'# +[\34.-\"+,-\"(4123Z5_]3-+46(44ij3.jneij41$3+%16s c` 3!#6.(n _\".] R+'4.jjkf`'\\..Y.(' i1 f%nG. $=i$#$ `'3V*+.b2&.!23+5.'n9\\\2ij&1j_3k^_n/+i_ij cd-$$11j(%3&'..\n!1$.4 623$ \2$' rs6${$\"\25($3-5.3''' $2.'\b(1( -.\0253,63''6 8\241+ 6\37 $-$I(P(($\252\253cZ/2\b'i4j3$86&4 j!k-J &1N]'+,fcY-ej/$fgl8 n4!$cd (^'$4+bc-g -2($.iZn$%Yc\20 4+Z,)$.'.\0071 1.'g1\37 4-$$%1'(D=+,-./+12 4,,7\f$ 1:3'+,?.='= #.%$)K!(123&(J3:4$J4 $52#(<! ,$AK;( !+# ./'1 \17 1\252\253<=>?@ABCDEFGHIJKLMNOPQRSTU ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; { { ; ; ; { ; ; { { ; ; { { { { { ; ; ; { { { { ; { { ; { { ; { { ; ; { { { ; { { { ; ; { { { ; ; { { { { { { { { { } ; { { { ; } } { { } } { { { { { } } { } } } } ; } } } { ; } } ; } } } } } } } ; } } } } } } } } } { } ; ; } } } }; ; ; } } { }; } }; ; ; ; ; ; ; ; ; ; ;; ; }; ; ; } ;; ; ; ; ; ; ; ; ; ;; ; ; ; ; {; ; ; ; ; ; } ; } ; ;;; } ; ; ; ; ;;; ; } };; } ; ;;; ;; ;;;; ;;; ;;;; ;; { ;;; ; ;; ; ; ; ;;; ; ;;; ;;;;;;;;; ;;;;;; ; ;; ;; ;; ;; ; ;; ;; ;; ;{ ;;;{ ;{ ;; ;{;;;; ;;;; {;{;; ;;;{ ;;; ;{ ;{ ; { { { { { { { } } ; ; ;; ;; ;{ \" ' !!!!$!!(8I!!,%&!!!#*)2. C!!CH'-/0@B+ L UJM< N4 [Q?DX[ Jc !ad' in fit` !w !V mL r L p z s Vv e x _ vb !VY o\\q j (x [|!E\"&@+10y?UJ W$ 6 [OPUDXAF]US Zj lac[q $n We y |) #w zk)Us |$ `Ub,5 )F8V_h;#4\"u% 0 $<CJUIJG $X < @67$X)Z$ | YUC])ZZ h dO m s<Ky < ^wUW x#${ oU@r Z 2 Ufg<$T| njv U+/[u(>1C$ \" . I4 U $+ Al 6M3UQ 8Uv+kV5 U;pBKU`P)jX Xe Cw }\" ++{UyZo$lC}*C,& .#C>'+ 52|4/B)7+ +|@1--9M6 L ||Q =P R ? )GH\\Vk[ [ f ICfB [[[!r 6 b$! UI!z[p |sC$)x[ U$IU[e+B XU >zU 0U-?$O @Yx:) 4EZCU/lUAco 'q.*9[}G_HLBI j(! m!!t , l x!q!|! ! !!!!! ! q$ ( $U! < c 'do nN)\"S w4k} = 0 A Y1+-9 =Scaf !OZ B F "
|
||||
|
||||
,C[3^9
|
||||
<<20],*k[
|
||||
4]={
|
||||
1+C,
|
||||
0,59
|
||||
+c}
|
||||
,**K
|
||||
,*l,*L,*
|
||||
o,O,p,
|
||||
|
||||
P,s,S=1,v=4 ;
|
||||
int V(int w){
|
||||
return
|
||||
1<w
|
||||
?3<
|
||||
w?4
|
||||
<w?
|
||||
5<w
|
||||
?6<
|
||||
|
||||
w?O=(O=*
|
||||
--l,O/64-
|
||||
1?1 &129
|
||||
>>O -39
|
||||
:27>(O%=
|
||||
32)&&0<O
|
||||
?1+ O:0
|
||||
),w +=O
|
||||
,O- (c[
|
||||
|
||||
|
||||
w]- 2)%
|
||||
28|| (1-
|
||||
(O= (c[
|
||||
w]- 2)/
|
||||
28) ?v=
|
||||
O:0 ,V(
|
||||
154+ 1950
|
||||
[w+c]+94*
|
||||
(464[w+
|
||||
|
||||
c+w ]/3
|
||||
%5+ 465
|
||||
[w+c +w]
|
||||
%26/7 )))
|
||||
:!( 3- v?2
|
||||
>v? L=1[k
|
||||
]=* k,3[
|
||||
k]= 67+
|
||||
c:3 >v?
|
||||
|
||||
V(0 ),p
|
||||
?(0 W L,
|
||||
*k- L W
|
||||
52+ c,
|
||||
1),p=
|
||||
0:0 ,L
|
||||
:L: (v=
|
||||
1,l =*k
|
||||
,V( 205
|
||||
|
||||
|
||||
),1-v
|
||||
?2 [k]
|
||||
=75 +c:
|
||||
o,V(
|
||||
3), v%3 ?2>
|
||||
v?V (1), o=
|
||||
1[k ]:L:(
|
||||
p=(P=1 W L,o
|
||||
-L W c +s,S
|
||||
|
||||
W o ,*k
|
||||
- o W c
|
||||
,S) ,L=
|
||||
*k) , 1[k
|
||||
]=* k )):
|
||||
(l= *k, V (
|
||||
808 ),v ):(
|
||||
v=* ++*k
|
||||
,39 -c[
|
||||
|
||||
v>> 7 ?
|
||||
15: 1-v
|
||||
/32 ?10
|
||||
-v?(312-v %
|
||||
32)/26+v/32
|
||||
*2: 13:
|
||||
82- v])
|
||||
:!( w[k
|
||||
]+= V(2
|
||||
|
||||
+w)
|
||||
,v=
|
||||
*w[
|
||||
k]%
|
||||
5,w
|
||||
[k]
|
||||
=*w
|
||||
[k]
|
||||
/5*
|
||||
|
||||
8+3+c):(K=k+w
|
||||
,33>*(*K-=!w)
|
||||
?*K
|
||||
+=w
|
||||
,V(
|
||||
w):
|
||||
!(*
|
||||
K+=
|
||||
!w)
|
||||
|
||||
);}int main()
|
||||
{ read(s,2+C,
|
||||
9<<
|
||||
20)
|
||||
;s=isatty(S)
|
||||
?S=
|
||||
5:9;
|
||||
for(;v;V(2))V
|
||||
(6);return P;}
|
||||
@@ -0,0 +1,286 @@
|
||||
#!/usr/bin/env make
|
||||
#
|
||||
# 2018 makefile
|
||||
#
|
||||
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
|
||||
# is licensed under:
|
||||
#
|
||||
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
|
||||
#
|
||||
# See: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
|
||||
################
|
||||
# tool locations
|
||||
################
|
||||
#
|
||||
SHELL= /bin/bash
|
||||
CP= cp
|
||||
CPP= cpp
|
||||
GUNZIP= gunzip
|
||||
BUNZIP2= bunzip2
|
||||
GZIP_PROG= gzip
|
||||
BZIP2= bzip2
|
||||
CURL= curl
|
||||
DD= dd
|
||||
LD= ld
|
||||
MAKE= make
|
||||
RM= rm
|
||||
SED= sed
|
||||
TAR= tar
|
||||
TRUE= true
|
||||
MKDIR= mkdir
|
||||
MV= mv
|
||||
TR= tr
|
||||
GREP= grep
|
||||
SORT= sort
|
||||
UNIQ= uniq
|
||||
|
||||
# Set X11_LIBDIR to the directory where the X11 library resides
|
||||
#
|
||||
#X11_LIBDIR= /usr/X11R6/lib
|
||||
#X11_LIBDIR= /usr/X11/lib
|
||||
X11_LIBDIR= /opt/X11/lib
|
||||
|
||||
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
|
||||
#
|
||||
#X11_INCDIR= /usr/X11R6/include
|
||||
#X11_INCDIR= /usr/X11/include
|
||||
X11_INCDIR= /opt/X11/include
|
||||
|
||||
# Compiler warnings
|
||||
#
|
||||
#CWARN=
|
||||
#CWARN= -Wall
|
||||
#CWARN= -Wall -Wextra
|
||||
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
|
||||
#CWARN= -Wall -Wextra -Weverything
|
||||
#CWARN= -Wall -Wextra -Weverything -pedantic
|
||||
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
|
||||
|
||||
# Silence warnings that ${CWARN} would normally complain about
|
||||
#
|
||||
CSILENCE=
|
||||
#CSILENCE= -Wno-implicit-int
|
||||
|
||||
# compiler standard
|
||||
#
|
||||
#CSTD=
|
||||
#CSTD= -ansi
|
||||
CSTD= -std=c11
|
||||
|
||||
# compiler bit architecture
|
||||
#
|
||||
# Some entries require 32-bitness:
|
||||
# ARCH= -m32
|
||||
#
|
||||
# Some entries require 64-bitness:
|
||||
# ARCH= -m64
|
||||
#
|
||||
# By default we assume nothing:
|
||||
#
|
||||
ARCH=
|
||||
|
||||
# defines that are needed to compile
|
||||
#
|
||||
CDEFINE=
|
||||
#CDEFINE= -DIOCCC=25
|
||||
|
||||
# include files that are needed to compile
|
||||
#
|
||||
CINCLUDE=
|
||||
#CINCLUDE= -include stdlib.h
|
||||
#CINCLUDE= -include stdio.h
|
||||
#CINCLUDE= -include stdlib.h -include stdio.h
|
||||
#CINCLUDE= -I ${X11_INCDIR}
|
||||
|
||||
# optimization
|
||||
#
|
||||
# Most compiles will safely use -O2. Some can use only -O1 or -O.
|
||||
# A few compilers have broken optimizers or this entry make break
|
||||
# under those buggy optimizers and thus you may not want anything.
|
||||
# Reasonable compilers will allow for -O3.
|
||||
#
|
||||
#OPT=
|
||||
#OPT= -O
|
||||
#OPT= -O1
|
||||
#OPT= -O2
|
||||
OPT= -O3
|
||||
|
||||
# default flags for ANSI C compilation
|
||||
#
|
||||
CFLAGS= ${CSTD} ${CWARN} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
|
||||
|
||||
# Libraries needed to build
|
||||
#
|
||||
LIBS=
|
||||
#LIBS= -L ${X11_LIBDIR}
|
||||
|
||||
# ANSI compiler
|
||||
#
|
||||
# Set CC to the name of your ANSI compiler.
|
||||
#
|
||||
# Some entries seem to need gcc. If you have gcc, set
|
||||
# both CC and MAY_NEED_GCC to gcc.
|
||||
#
|
||||
# If you do not have gcc, set CC to the name of your ANSI compiler, and
|
||||
# set MAY_NEED_GCC to either ${CC} (and hope for the best) or to just :
|
||||
# to disable such programs.
|
||||
#
|
||||
CC= cc
|
||||
#CC=clang
|
||||
MAY_NEED_GCC= gcc
|
||||
|
||||
|
||||
##############################
|
||||
# Special flags for this entry
|
||||
##############################
|
||||
#
|
||||
OBJ= prog.o
|
||||
DATA=
|
||||
TARGET= prog
|
||||
#
|
||||
ALT_OBJ=
|
||||
ALT_TARGET= prog.orig
|
||||
|
||||
|
||||
#################
|
||||
# build the entry
|
||||
#################
|
||||
#
|
||||
all: ${TARGET} ${DATA}
|
||||
@${TRUE}
|
||||
|
||||
prog: prog.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
# alternative executable
|
||||
#
|
||||
alt: ${ALT_TARGET}
|
||||
@${TRUE}
|
||||
|
||||
prog.orig: prog.orig.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
# data files
|
||||
#
|
||||
data: ${DATA}
|
||||
@${TRUE}
|
||||
|
||||
|
||||
###############
|
||||
# utility rules
|
||||
###############
|
||||
#
|
||||
everything: all alt
|
||||
|
||||
clean:
|
||||
${RM} -f ${OBJ} ${ALT_OBJ}
|
||||
|
||||
clobber: clean
|
||||
${RM} -f ${TARGET} ${ALT_TARGET}
|
||||
@-if [ -e sandwich ]; then \
|
||||
${RM} -f sandwich; \
|
||||
echo 'ate sandwich'; \
|
||||
fi
|
||||
|
||||
nuke: clobber
|
||||
@${TRUE}
|
||||
|
||||
dist_clean: nuke
|
||||
@${TRUE}
|
||||
|
||||
install:
|
||||
@echo "Surely you are performing, Dr. May!"
|
||||
@${TRUE}
|
||||
|
||||
# backwards compatibility
|
||||
#
|
||||
build: all
|
||||
@${TRUE}
|
||||
|
||||
|
||||
##################
|
||||
# 133t hacker rulz
|
||||
##################
|
||||
#
|
||||
love:
|
||||
@echo 'not war?'
|
||||
@${TRUE}
|
||||
|
||||
haste:
|
||||
$(MAKE) waste
|
||||
@${TRUE}
|
||||
|
||||
waste:
|
||||
@echo 'haste'
|
||||
@${TRUE}
|
||||
|
||||
make:
|
||||
@echo 'Attend a maker faire'
|
||||
@${TRUE}
|
||||
|
||||
easter_egg:
|
||||
@echo you expected to often mis-understand this $${RANDOM} magic
|
||||
@echo chongo '<was here>' "/\\oo/\\"
|
||||
@echo Eggy
|
||||
|
||||
fabricate fashion form frame manufacture produce: make
|
||||
@${TRUE}
|
||||
|
||||
sandwich:
|
||||
@if [ `id -u` -eq 0 ]; then \
|
||||
echo 'Okay.'; \
|
||||
echo $${RANDOM}`date +%s`$${RANDOM} > $@; \
|
||||
else \
|
||||
echo 'What? Make it yourself.'; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
# Understand the history of the Homebrew Computer Club
|
||||
# as well as the West Coast Computer Faire and
|
||||
# you might be confused different. :-)
|
||||
#
|
||||
supernova: nuke
|
||||
@-if [ -r .code_anal ]; then \
|
||||
${RM} -f .code_anal_v6; \
|
||||
else \
|
||||
echo "planet deniers, like some members of the IAU, are so cute when they try to defend their logic"; \
|
||||
fi
|
||||
@echo A $@ helps ${MAKE} the elements that help form planets
|
||||
@${TRUE}
|
||||
|
||||
deep_magic:
|
||||
@-if [ -r .code_anal ]; then \
|
||||
ccode_analysis --deep_magic 3a3fabb90892eeb2f610ae0f74a35a970060665a063ab702bd686c17c4ae07f6 --FNV1a_hash_256_bit "prog"; \
|
||||
else \
|
||||
echo "Wrong! Do it again!"; \
|
||||
sleep 2; \
|
||||
echo "Wrong! Do it again!"; \
|
||||
sleep 2; \
|
||||
echo "Wrong! Do it again!"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
|
||||
magic: deep_magic
|
||||
@-if [ -r .code_anal ]; then \
|
||||
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_256_bit "prog"; \
|
||||
else \
|
||||
echo "If you don't eat yer meat, you can't have any pudding!"; \
|
||||
echo "How can you have any pudding if you don't eat yer meat?!"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
|
||||
# The IOCCC resident astronomer states
|
||||
#
|
||||
charon: supernova
|
||||
@echo $@ is a dwarf planet
|
||||
@echo dwarf is a type of planet
|
||||
@echo $@ is a planet
|
||||
|
||||
pluto: supernova
|
||||
${MAKE} charon
|
||||
@echo $@ is a dwarf planet
|
||||
@echo dwarf is a type of planet
|
||||
@echo $@ is a planet
|
||||
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
|
||||
@@ -0,0 +1,29 @@
|
||||
o o n n
|
||||
ROBBB0BDROORD0O06 &pqQ6 &Q8oo SEF H3yNK
|
||||
0O0RBOBODBO0BBBO0e o88oQp po&&pqP m5NF3UK M2EUGZZZ
|
||||
00ODRBBDRDOOROR0R0 QQQP&o&Qqo&Qpp& KZUUWySW2 WmWUNEUF
|
||||
DDO0000BBDBOBR0DR oP q&o UZH5EmhWUM5 252EU
|
||||
B RRR 8q Q SU2UmSFFEhG E
|
||||
&BR RRO 8&p Q NF HE3KEGyE3HyS
|
||||
dRB DO0 &P& P h2NHU WNWhE255FN5N
|
||||
6ap0BOO 0DR oPq q8o888q8P8Q KZyKHyS Sy5HmFUh3F
|
||||
DOBDDO0O DDB qPp P&p88&o8ppp 2mh52HW3 52Z2ZKZG
|
||||
DBD0DBBB DBR Pq qPpPoPQoPQo 3SWyKFH MFHU
|
||||
0DB0D0R DB Q qqPPPq8Q8p ZF5ZZZZ G
|
||||
|
||||
o
|
||||
P oOBD
|
||||
po8 BOOOBD
|
||||
Qq&P BOROO
|
||||
KHy pp p8 8& DBD o8qQQpqPp BOOOB oO
|
||||
mUGFGMHMH QQQp&P&&PQQ pp&PP8 DDORBRORB 8&pQoqQ&P8 BR0BOOO0OR0
|
||||
WHyZSNmUMUU3N pPpp& 88oQP ooPoq8 B0OORBB0OO0DO qpQo B00ROOBDBDRB
|
||||
N35H 3hUS QpQq pQ8o QQqP BOBO RDBR Qoop ODBB0 BRBB0
|
||||
SUHH ZhN 8Qq8 8QqP &Q&Q 00BD DRB 8Q&q 0DB0R DDO0O
|
||||
3M522N 8QqP pQP& oPpP ROBDOO oQPQ 00OBO BORRO
|
||||
NyUNyHMZEFSNS &poPp PqpP& oqo&Q 0BRBD00D0RDRR P&&qqp&&Q DBB0DRBB 0000
|
||||
hEhKNMMGE qq8op &88&Q oqqoo DOB0RB00D qPqoQ&p OODRORBB OOB
|
||||
hK PP && pq BO oQ BO D0O
|
||||
ROB
|
||||
RR0O
|
||||
DRR
|
||||
@@ -0,0 +1,86 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
|
||||
<link rel="stylesheet"
|
||||
type="text/css"
|
||||
href="../hint.css">
|
||||
<title>Best tool to reveal holes</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Best tool to reveal holes</h1>
|
||||
|
||||
<p>Yusuke Endoh<br>
|
||||
Twitter: @mametter</p>
|
||||
|
||||
<h2>Judges' comments:</h2>
|
||||
|
||||
<h3>To use:</h3>
|
||||
|
||||
<pre><code>make
|
||||
./prog < textfile > output.gif
|
||||
</code></pre>
|
||||
|
||||
<h3>Try:</h3>
|
||||
|
||||
<pre><code>./prog < golem.txt > golem.gif
|
||||
./prog < smily.txt > smily.gif
|
||||
</code></pre>
|
||||
|
||||
<h3>Selected Judges Remarks:</h3>
|
||||
|
||||
<p>To get the best experience, use a GIF viewer that can handle animated gifs.
|
||||
On OS X you can use Safari using “open -a Safari smily.gif”</p>
|
||||
|
||||
<p>Some things to consider are that this 2.5KiB gem encodes a 96 character 8x8
|
||||
font (naively this could already take 6144 bytes) and a GIF encoder. But
|
||||
how does it know which characters are closed?</p>
|
||||
|
||||
<p>You should only give this program printable ASCII characters.</p>
|
||||
|
||||
<p>Unfortunately this won’t run on your PDP8, if you had one, as it needs at
|
||||
least 2MiB of memory to run in.</p>
|
||||
|
||||
<h2>Author’s comments:</h2>
|
||||
|
||||
<p>This program generates an animated GIF from a plain text. Run:</p>
|
||||
|
||||
<pre><code>gcc -o prog prog.c
|
||||
./prog < invisible.txt > invisible.gif
|
||||
</code></pre>
|
||||
|
||||
<p>Open invisible.gif and then wait a minute. You will see a hidden message.
|
||||
Can you tell the difference between letters that leaves the mark and ones that does not?</p>
|
||||
|
||||
<p>Other examples:</p>
|
||||
|
||||
<pre><code>./prog < golem.txt > golem.gif
|
||||
./prog < smily.txt > smily.gif
|
||||
</code></pre>
|
||||
|
||||
<p>The program itself has a hidden message.</p>
|
||||
|
||||
<pre><code>./prog < prog.c > prog.gif
|
||||
</code></pre>
|
||||
|
||||
<hr />
|
||||
|
||||
<!--
|
||||
(c) Copyright 1984-2018, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
|
||||
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
|
||||
|
||||
[judges]: http://www.ioccc.org/judges.html
|
||||
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
-->
|
||||
|
||||
<TABLE><TR>
|
||||
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
|
||||
<TD><P>© Copyright 1984-2018,
|
||||
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
|
||||
- All rights reserved<BR>
|
||||
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
|
||||
<TD> <!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
|
||||
</TR></TABLE>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,57 @@
|
||||
# Best tool to reveal holes
|
||||
|
||||
Yusuke Endoh
|
||||
Twitter: @mametter
|
||||
|
||||
|
||||
## Judges' comments:
|
||||
### To use:
|
||||
|
||||
make
|
||||
./prog < textfile > output.gif
|
||||
|
||||
### Try:
|
||||
|
||||
./prog < golem.txt > golem.gif
|
||||
./prog < smily.txt > smily.gif
|
||||
|
||||
### Selected Judges Remarks:
|
||||
|
||||
To get the best experience, use a GIF viewer that can handle animated gifs.
|
||||
On OS X you can use Safari using "open -a Safari smily.gif"
|
||||
|
||||
Some things to consider are that this 2.5KiB gem encodes a 96 character 8x8
|
||||
font (naively this could already take 6144 bytes) and a GIF encoder. But
|
||||
how does it know which characters are closed?
|
||||
|
||||
You should only give this program printable ASCII characters.
|
||||
|
||||
Unfortunately this won't run on your PDP8, if you had one, as it needs at
|
||||
least 2MiB of memory to run in.
|
||||
|
||||
## Author's comments:
|
||||
This program generates an animated GIF from a plain text. Run:
|
||||
|
||||
gcc -o prog prog.c
|
||||
./prog < invisible.txt > invisible.gif
|
||||
|
||||
Open invisible.gif and then wait a minute. You will see a hidden message.
|
||||
Can you tell the difference between letters that leaves the mark and ones that does not?
|
||||
|
||||
Other examples:
|
||||
|
||||
./prog < golem.txt > golem.gif
|
||||
./prog < smily.txt > smily.gif
|
||||
|
||||
The program itself has a hidden message.
|
||||
|
||||
./prog < prog.c > prog.gif
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
<!--
|
||||
(c) Copyright 1984-2018, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
|
||||
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
|
||||
|
||||
[judges]: http://www.ioccc.org/judges.html
|
||||
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
-->
|
||||
@@ -0,0 +1,12 @@
|
||||
TELUGU INEFFECTIVENESS SHEETS CYSTIC SHIFTINESS FLESHIEST UNSUCCESSFULLY WEIGHTLESSNESS FLESH HUFFIEST
|
||||
LIFE FLOORBOARD CHESSBOARD APPROACHES CARDBOARD TINY POPPA PAROXYSMS ARBOR BARBARIC JARROD DOODAD SLIT
|
||||
WUSS BARODA PROBATE CORPORA PAPOOSE WOODARD PARADE SEABOARD BROAD SHIPBOARD PARADIGM ABOARD BOARD NIGH
|
||||
LIMY ORDAIN MBABANE UPDRAFTS SLUTS FERRARI TERRORS INROAD ENTRAPPING PROPHETESSES LIKEN CAPRA NEGLECTS
|
||||
INESCAPABLY HINES SKEDADDLES FUNNY GEARBOX JELLYFISH PROPS STARDOM TEAROOM ENTHUSING KICKAPOO JUSTNESS
|
||||
GUNS PRADO BRAD MICK DROOP ADORABLE CARBOYS MCKINNEY PRADA ARDOR SIGNBOARD BARBRA LEVITT BORON WISTFUL
|
||||
NIFTY ERROR QADDAFI SAPPORO RADAR STEPDAD EYEFULS CLIPBOARD PARAFFIN ABROAD PROPONENT ESTRADA IMMUNITY
|
||||
INSENSITIVE VAPOR GUMDROP MIXTEC HETERODOX SEEKING STRADDLES BARON THROBBING WILTING SCHIAPARELLI TUMS
|
||||
UNMEMORABLE NARROWLY ARABS SECS KLEE POOP TEMPORAL FEDORA STUBBORN SCRAPPIEST SEVENTHS UNBARRING TYING
|
||||
ZINC BAOBAB BROADEST DOBRO BARROOM SCABBARD ODDBALLS BOOBING PROPELS BROOD RAPPROCHEMENT ADORNS SWEETS
|
||||
GENUS CORROBORATES TEARDROP PARBOILING BOARDROOM INEXORABLY HADDOCK CORDOBA PADDOCKS VIVIPAROUS HUGEST
|
||||
TEXT SLUM THICKLY FUZZIEST JUNKETING SINGEING INSUFFICIENTLY CIVET INSENSITIVITY LESSENS SINE NICETIES
|
||||
@@ -0,0 +1,27 @@
|
||||
#define/*__Int3rn^ti[]n/l_()I3fusc^t3|]_C_C<>I7E_C[]nt3st__*/L/*__MMXVIII__*/for
|
||||
#include/*!"'()*+,-./12357:;<=>?CEFGHIJKLMNSTUVWXYZ[]^_`cfhijklmnrstuvwxyz{|}*/<stdio.h>
|
||||
char*r,F[1<<21]="~T/}3(|+G{>/zUhy;Jx+5wG<v>>u55t.?sIZrC]n.;m+:l+Hk]WjNJi/Sh+2f1>c2H`)(_2(^L\
|
||||
-]=([1/Z<2Y7/X12W:.VFFU1,T77S+;N?;M/>L..K1+JCCI<<H:(G*5F--E11C=5?.(>+(=3)Z-;*(:*.Y/5(-=)2*-U,\
|
||||
/+-?5'(,+++***''EE>T,215IEUF:N`2`:?GK;+^`+?>)5?>U>_)5GxG).2K.2};}_235(]:5,S7E1(vTSS,-SSTvU(<-HG\
|
||||
-2E2/2L2/EE->E:?EE,2XMMMM1Hy`)5rHK;+.T+?[n2/_2{LKN2/_|cK2+.2`;}:?{KL57?|cK:2{NrHKtMMMK2nrH;rH[n"
|
||||
"CkM_E21-E,-1->E(_:mSE/LhLE/mm:2Ul;2M>,2KW-+.-u).5Lm?fM`2`2nZXjj?[n<YcK?2}yC}H[^7N7LX^7N7UN</:-\
|
||||
ZWXI<^I2K?>T+?KH~-?f<;G_x2;;2XT7LXIuuVF2X(G(GVV-:-:KjJ]HKLyN7UjJ3.WXjNI2KN<l|cKt2~[IsHfI2w{[<VV"
|
||||
"GIfZG>x#&#&&$#$;ZXIc###$&$$#>7[LMv{&&&&#&##L,l2TY.&$#$#&&$,(iiii,#&&&#$#$?TY2.$#$1(x###;2EE[t,\
|
||||
SSEz.SW-k,T&&jC?E-.$## &#&57+$$# &&&W1-&$$7W -J$#$kEN&#& $##C^+$##W,h###n/+L2YE"
|
||||
"2nJk/H;YNs#$[,:TU(#$ ,: &&~H>&# Y; &&G_x ,mT&$YE-#& 5G $#VVF$#&zNs$$&Ej]HELy\
|
||||
CN/U^Jk71<(#&:G7E+^&# l|?1 $$Y.2$$ 7lzs WzZw>&$E -<V-wE(2$$ G>x; 2zsW/$$#HKt&$$v>+t1(>"
|
||||
"7>S7S,;TT,&$;S7S>7&#>E_::U $$'",op ,*G= F,*I=957+F ;int*t,k,O, i, j,T[+060<<+020];int M(
|
||||
int m,int nop){;;;return+ m%(0+nop );;} int*tOo,w, h,z,W;void(C) (int n){n=putchar(n);}int
|
||||
f,c,H=11,Y=64<<2,Z,pq,X ;void(E/*d */)( int/*RP*/n ){L(Z=k+00; Z; Z/=+2+000)G[000]=*G*!!f
|
||||
|M(n,2)<<f,pq=2,f=+06 <f?++pq,++pq ,G++ ,z:f+001,n /=2;;}void (V)( int/*opqrstabd*/n){C(n
|
||||
%Y);;C(n/Y+00);;}void J(){L(pq--,pq =j =O=-1+0;++ j<240;I[6+ (h +6+j/12/2*2+M(j/2,2))*
|
||||
W+M(j/2/2,+06)*2+w*014 +00+M(00+ 000+j,002 +00)]=000 +00+k)k=M(G[j/2/2+(*r-+
|
||||
32)**"<nopqabdeg"],/*4649&96#*/3);/*&oaogoqo*/;}/*xD%P$Q#Rq*/int/*dbqpdbqpxyzzyboo3570OQ*/main()
|
||||
{L(X=Y-1;i<21*3;i++,I++)L(r=G,G+=2;*G++;)*G>=13*3?*G-*r?*I++=*G:(*I++=r[1],*I++=r[2]):1;L(j=12,r
|
||||
=I;(*I=i=getchar())>-1;I++)i-7-3?I-=i<32||127<=i,j+=12:(H+=17+3,W=W<j?j:W,j=12);L(;*r>-1;r++)*r-
|
||||
7-3?J(),w++:(w=z,h+=17+3);C(71);C(73);V('*'*'1'*7);C(57);C(32*3+1);V(W);V(H);C(122*2);L(V(i=z);i
|
||||
<32*3;)C(i++/3*X/31);C(33);C(X);C(11);L(G="SJYXHFUJ735";*G;)C(*G++-5);C(3);V(1);L(V(j=z);j<21*3;
|
||||
j++){k=257;V(63777);V(k<<2);V(M(j,32)?11:511);V(z);C(22*2);V(i=f=z);V(z);V(W);V(H);V(1<<11);r=
|
||||
G=I+W*H;L(t=T;i<1<<21;i++)T[i]=i<Y?i:-1;E(Y);L(i=-1;++i<W*H;t=T+Z*Y+Y)c=I[i]?I[i]*31-31:(31<
|
||||
j?j-31:31-j),Z=c[t[c]<z?E(Z),k<(1<<12)-2?t[c]=++k,T:T:t];E(Z);E(257);L(G++;k=G-r>X?X:G-r
|
||||
,C(k),k;)L(;k--;C(*r++/*---#$%&04689@ABDOPQRabdegopq---*/));}C(53+6);return(z);}
|
||||
@@ -0,0 +1,27 @@
|
||||
#define/*__Int3rn^ti[]n/l_()I3fusc^t3|]_C_C<>I7E_C[]nt3st__*/L/*__MMXVIII__*/for
|
||||
#include/*!"'()*+,-./12357:;<=>?CEFGHIJKLMNSTUVWXYZ[]^_`cfhijklmnrstuvwxyz{|}*/<stdio.h>
|
||||
char*r,F[1<<21]="~T/}3(|+G{>/zUhy;Jx+5wG<v>>u55t.?sIZrC]n.;m+:l+Hk]WjNJi/Sh+2f1>c2H`)(_2(^L\
|
||||
-]=([1/Z<2Y7/X12W:.VFFU1,T77S+;N?;M/>L..K1+JCCI<<H:(G*5F--E11C=5?.(>+(=3)Z-;*(:*.Y/5(-=)2*-U,\
|
||||
/+-?5'(,+++***''EE>T,215IEUF:N`2`:?GK;+^`+?>)5?>U>_)5GxG).2K.2};}_235(]:5,S7E1(vTSS,-SSTvU(<-HG\
|
||||
-2E2/2L2/EE->E:?EE,2XMMMM1Hy`)5rHK;+.T+?[n2/_2{LKN2/_|cK2+.2`;}:?{KL57?|cK:2{NrHKtMMMK2nrH;rH[n"
|
||||
"CkM_E21-E,-1->E(_:mSE/LhLE/mm:2Ul;2M>,2KW-+.-u).5Lm?fM`2`2nZXjj?[n<YcK?2}yC}H[^7N7LX^7N7UN</:-\
|
||||
ZWXI<^I2K?>T+?KH~-?f<;G_x2;;2XT7LXIuuVF2X(G(GVV-:-:KjJ]HKLyN7UjJ3.WXjNI2KN<l|cKt2~[IsHfI2w{[<VV"
|
||||
"GIfZG>x#&#&&$#$;ZXIc###$&$$#>7[LMv{&&&&#&##L,l2TY.&$#$#&&$,(iiii,#&&&#$#$?TY2.$#$1(x###;2EE[t,\
|
||||
SSEz.SW-k,T&&jC?E-.$## &#&57+$$# &&&W1-&$$7W -J$#$kEN&#& $##C^+$##W,h###n/+L2YE"
|
||||
"2nJk/H;YNs#$[,:TU(#$ ,: &&~H>&# Y; &&G_x ,mT&$YE-#& 5G $#VVF$#&zNs$$&Ej]HELy\
|
||||
CN/U^Jk71<(#&:G7E+^&# l|?1 $$Y.2$$ 7lzs WzZw>&$E -<V-wE(2$$ G>x; 2zsW/$$#HKt&$$v>+t1(>"
|
||||
"7>S7S,;TT,&$;S7S>7&#>E_::U $$'",op ,*G= F,*I=957+F ;int*t,k,O, i, j,T[+060<<+020];int M(
|
||||
int m,int nop){;;;return+ m%(0+nop );;} int*tOo,w, h,z,W;void(C) (int n){n=putchar(n);}int
|
||||
f,c,H=11,Y=64<<2,Z,pq,X ;void(E/*d */)( int/*RP*/n ){L(Z=k+00; Z; Z/=+2+000)G[000]=*G*!!f
|
||||
|M(n,2)<<f,pq=2,f=+06 <f?++pq,++pq ,G++ ,z:f+001,n /=2;;}void (V)( int/*opqrstabd*/n){C(n
|
||||
%Y);;C(n/Y+00);;}void J(){L(pq--,pq =j =O=-1+0;++ j<240;I[6+ (h +6+j/12/2*2+M(j/2,2))*
|
||||
W+M(j/2/2,+06)*2+w*014 +00+M(00+ 000+j,002 +00)]=000 +00+k)k=M(G[j/2/2+(*r-+
|
||||
32)**"<nopqabdeg"],/*4649&96#*/3);/*&oaogoqo*/;}/*xD%P$Q#Rq*/int/*dbqpdbqpxyzzyboo3570OQ*/main()
|
||||
{L(X=Y-1;i<21*3;i++,I++)L(r=G,G+=2;*G++;)*G>=13*3?*G-*r?*I++=*G:(*I++=r[1],*I++=r[2]):1;L(j=12,r
|
||||
=I;(*I=i=getchar())>-1;I++)i-7-3?I-=i<32||127<=i,j+=12:(H+=17+3,W=W<j?j:W,j=12);L(;*r>-1;r++)*r-
|
||||
7-3?J(),w++:(w=z,h+=17+3);C(71);C(73);V('*'*'1'*7);C(57);C(32*3+1);V(W);V(H);C(122*2);L(V(i=z);i
|
||||
<32*3;)C(i++/3*X/31);C(33);C(X);C(11);L(G="SJYXHFUJ735";*G;)C(*G++-5);C(3);V(1);L(V(j=z);j<21*3;
|
||||
j++){k=257;V(63777);V(k<<2);V(M(j,32)?11:511);V(z);C(22*2);V(i=f=z);V(z);V(W);V(H);V(1<<11);r=
|
||||
G=I+W*H;L(t=T;i<1<<21;i++)T[i]=i<Y?i:-1;E(Y);L(i=-1;++i<W*H;t=T+Z*Y+Y)c=I[i]?I[i]*31-31:(31<
|
||||
j?j-31:31-j),Z=c[t[c]<z?E(Z),k<(1<<12)-2?t[c]=++k,T:T:t];E(Z);E(257);L(G++;k=G-r>X?X:G-r
|
||||
,C(k),k;)L(;k--;C(*r++/*---#$%&04689@ABDOPQRabdegopq---*/));}C(53+7);return(z);}
|
||||
@@ -0,0 +1,30 @@
|
||||
8BOQQQ0QBD8ROO8
|
||||
D0RRO0B0BOuxcncnvQO0QBQQRO0
|
||||
00OD8QcvxvnnxnxuxuvvnuuuuQRQRDQ
|
||||
ORQB8uvxcxxxcxxxnxcvnuucnnuvxDOBQD
|
||||
DBOB0nvvcvcvuvcccvcxuvcuvuxvcncvcOOROR
|
||||
QRDQOxnnvcvcnnncnvvnxcxnxccxucnnnun80RBB
|
||||
Q0OO8ccunnuvncuuxnncvcvxccncnxvcxnvccuBQR8
|
||||
BBQQ0uucvvxcuvcuxvvnunxncvnnuuncncnxxnuc8QDRB
|
||||
00D0xvxxvccuvxccuuuuvncuxcuuvnnvxnxccnnccncOBD0
|
||||
O8OQxxunvxxvxMNMNNGnncxxvvxuccNHMHMNvcxxvuvncOD8Q
|
||||
D0D0xunnnnooMGNHGNMHNGuvxnnvnGGGHNMMHGHooucuccRR00
|
||||
0ROQnxuxncvo0888nnvnMNNNxuxccNGMHvvucQ88DouunnvxQBRQ
|
||||
D0O8uxxvnncuHB0BooooRGMGccxcxNNNOooooBQQMucxncnnQR0D
|
||||
QDQOcvncuxcuMB08ooouHQ0QoooooD8BHxooo0R8HvvcuvvxDDQR
|
||||
ROB8vnnvcucvxuuooooovvxcxvxvuxnunooooovncvnvcnnuOBOD
|
||||
Q8RBccnxxcvxxcuoooooxcuccvnunuuxvooooovcncvcvvuc0QBR
|
||||
DBD8uncnxvunuvuuooocnxuuxnvcxuvcxuooonxuvxcnxxnvQ0D0
|
||||
RBQDxvuxnvMGMNGGMMHvxxuuxxvxuvxnunMHMNHMGMGxnvunDQ8O
|
||||
DQ8QnvcccuMNMMMMGNMnxuvuxuxuvcvvvcMGHHNGHGHcucxxBOD0
|
||||
BR88uxnnvcHNGGGGMMGHnvcxcxxxvucGMNGGHGNNMxccnn088B
|
||||
OROOuuuxuxGGNMNNMBRDRROoooQDQRRDMMHNNHNnxccnO0B8
|
||||
80BBnnncxxvDQQR8BDB0O80QOQDRB0RRBROOcxunnv00RO
|
||||
B00OOccccuvnNNRO8MNHMMGMHMMG0BQGHcnuxvux0ORDQ
|
||||
QBQB8uvvxvvuuuoGHNGGNMNMHMNGocuuuuncnvQDRD
|
||||
BDB0Rcxcucuccovncxnxcucvuxcocucnxcc0DB8O
|
||||
BO0ODcxcucvnxvuxcucvvununuuxnnvcvO8ROB
|
||||
QQ08Bvxuncnnuvnccvvuxcnuvnxvx8QBQ8
|
||||
BQBRBRvxxuuuunuvnvuxnxvvnRRBDBO
|
||||
D8Q00QQOD8ucccvxc80OO0OQBRD
|
||||
O0D0Q0BQOD8BD8R
|
||||
@@ -0,0 +1,308 @@
|
||||
#!/usr/bin/env make
|
||||
#
|
||||
# 2018 makefile
|
||||
#
|
||||
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
|
||||
# is licensed under:
|
||||
#
|
||||
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
|
||||
#
|
||||
# See: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
|
||||
################
|
||||
# tool locations
|
||||
################
|
||||
#
|
||||
SHELL= /bin/bash
|
||||
CP= cp
|
||||
CPP= cpp
|
||||
GUNZIP= gunzip
|
||||
BUNZIP2= bunzip2
|
||||
GZIP_PROG= gzip
|
||||
BZIP2= bzip2
|
||||
CURL= curl
|
||||
DD= dd
|
||||
LD= ld
|
||||
MAKE= make
|
||||
RM= rm
|
||||
SED= sed
|
||||
TAR= tar
|
||||
TRUE= true
|
||||
MKDIR= mkdir
|
||||
MV= mv
|
||||
TR= tr
|
||||
GREP= grep
|
||||
SORT= sort
|
||||
UNIQ= uniq
|
||||
STRIP= strip
|
||||
|
||||
# Set X11_LIBDIR to the directory where the X11 library resides
|
||||
#
|
||||
#X11_LIBDIR= /usr/X11R6/lib
|
||||
#X11_LIBDIR= /usr/X11/lib
|
||||
X11_LIBDIR= /opt/X11/lib
|
||||
|
||||
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
|
||||
#
|
||||
#X11_INCDIR= /usr/X11R6/include
|
||||
#X11_INCDIR= /usr/X11/include
|
||||
X11_INCDIR= /opt/X11/include
|
||||
|
||||
# Compiler warnings
|
||||
#
|
||||
#CWARN=
|
||||
#CWARN= -Wall
|
||||
#CWARN= -Wall -Wextra
|
||||
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
|
||||
#CWARN= -Wall -Wextra -Weverything
|
||||
#CWARN= -Wall -Wextra -Weverything -pedantic
|
||||
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
|
||||
|
||||
# Silence warnings that ${CWARN} would normally complain about
|
||||
#
|
||||
CSILENCE=
|
||||
#CSILENCE= -Wno-implicit-int
|
||||
|
||||
# compiler standard
|
||||
#
|
||||
#CSTD=
|
||||
#CSTD= -ansi
|
||||
CSTD= -std=c11
|
||||
|
||||
# compiler bit architecture
|
||||
#
|
||||
# Some entries require 32-bitness:
|
||||
# ARCH= -m32
|
||||
#
|
||||
# Some entries require 64-bitness:
|
||||
# ARCH= -m64
|
||||
#
|
||||
# By default we assume nothing:
|
||||
#
|
||||
ARCH=
|
||||
|
||||
# defines that are needed to compile
|
||||
#
|
||||
CDEFINE=
|
||||
#CDEFINE= -DIOCCC=25
|
||||
|
||||
# include files that are needed to compile
|
||||
#
|
||||
CINCLUDE=
|
||||
#CINCLUDE= -include stdlib.h
|
||||
#CINCLUDE= -include stdio.h
|
||||
#CINCLUDE= -include stdlib.h -include stdio.h
|
||||
#CINCLUDE= -I ${X11_INCDIR}
|
||||
|
||||
# optimization
|
||||
#
|
||||
# Most compiles will safely use -O2. Some can use only -O1 or -O.
|
||||
# A few compilers have broken optimizers or this entry make break
|
||||
# under those buggy optimizers and thus you may not want anything.
|
||||
# Reasonable compilers will allow for -O3.
|
||||
#
|
||||
#OPT=
|
||||
#OPT= -O
|
||||
#OPT= -O1
|
||||
#OPT= -O2
|
||||
OPT= -O3
|
||||
|
||||
# default flags for ANSI C compilation
|
||||
#
|
||||
CFLAGS= ${CSTD} ${CWARN} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
|
||||
|
||||
# Libraries needed to build
|
||||
#
|
||||
LIBS=
|
||||
#LIBS= -L ${X11_LIBDIR}
|
||||
|
||||
# ANSI compiler
|
||||
#
|
||||
# Set CC to the name of your ANSI compiler.
|
||||
#
|
||||
# Some entries seem to need gcc. If you have gcc, set
|
||||
# both CC and MAY_NEED_GCC to gcc.
|
||||
#
|
||||
# If you do not have gcc, set CC to the name of your ANSI compiler, and
|
||||
# set MAY_NEED_GCC to either ${CC} (and hope for the best) or to just :
|
||||
# to disable such programs.
|
||||
#
|
||||
CC= cc
|
||||
#CC=clang
|
||||
MAY_NEED_GCC= gcc
|
||||
|
||||
|
||||
##############################
|
||||
# Special flags for this entry
|
||||
##############################
|
||||
#
|
||||
OBJ= prog.o
|
||||
DATA=
|
||||
TARGET= prog
|
||||
#
|
||||
ALT_OBJ=
|
||||
ALT_TARGET=
|
||||
|
||||
|
||||
#################
|
||||
# build the entry
|
||||
#################
|
||||
#
|
||||
all: ${TARGET} ${DATA}
|
||||
@${TRUE}
|
||||
|
||||
prog: prog.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
prog_next.c: prog
|
||||
@${RM} -f $@
|
||||
./prog | tee $@
|
||||
|
||||
prog_next: prog_next.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
# alternative executable
|
||||
#
|
||||
alt: ${ALT_TARGET}
|
||||
@${TRUE}
|
||||
|
||||
# data files
|
||||
#
|
||||
data: ${DATA}
|
||||
@${TRUE}
|
||||
|
||||
python: prog
|
||||
@${RM} -f prog_next.c
|
||||
${CC} ${CFLAGS} prog.c -o prog ${LIBS}
|
||||
while :; do \
|
||||
./prog | tee prog_next.c; \
|
||||
${CC} ${CFLAGS} prog_next.c -o ./prog ${LIBS}; \
|
||||
sleep 1; \
|
||||
done
|
||||
|
||||
python3: prog
|
||||
@${RM} -f prog_next.c
|
||||
${CC} ${CFLAGS} prog.c -o prog ${LIBS}
|
||||
while :; do \
|
||||
./prog | tee prog_next.c; \
|
||||
${CC} ${CFLAGS} prog_next.c -o ./prog ${LIBS}; \
|
||||
done
|
||||
|
||||
###############
|
||||
# utility rules
|
||||
###############
|
||||
#
|
||||
everything: all alt
|
||||
|
||||
clean:
|
||||
${RM} -f ${OBJ} ${ALT_OBJ}
|
||||
|
||||
clobber: clean
|
||||
${RM} -f ${TARGET} ${ALT_TARGET}
|
||||
${RM} -f prog_next.c prog_next
|
||||
@-if [ -e sandwich ]; then \
|
||||
${RM} -f sandwich; \
|
||||
echo 'ate sandwich'; \
|
||||
fi
|
||||
|
||||
nuke: clobber
|
||||
@${TRUE}
|
||||
|
||||
dist_clean: nuke
|
||||
@${TRUE}
|
||||
|
||||
install:
|
||||
@echo "Surely you are performing, Dr. May!"
|
||||
@${TRUE}
|
||||
|
||||
# backwards compatibility
|
||||
#
|
||||
build: all
|
||||
@${TRUE}
|
||||
|
||||
|
||||
##################
|
||||
# 133t hacker rulz
|
||||
##################
|
||||
#
|
||||
love:
|
||||
@echo 'not war?'
|
||||
@${TRUE}
|
||||
|
||||
haste:
|
||||
$(MAKE) waste
|
||||
@${TRUE}
|
||||
|
||||
waste:
|
||||
@echo 'haste'
|
||||
@${TRUE}
|
||||
|
||||
make:
|
||||
@echo 'Attend a maker faire'
|
||||
@${TRUE}
|
||||
|
||||
easter_egg:
|
||||
@echo you expected to often mis-understand this $${RANDOM} magic
|
||||
@echo chongo '<was here>' "/\\oo/\\"
|
||||
@echo Eggy
|
||||
|
||||
fabricate fashion form frame manufacture produce: make
|
||||
@${TRUE}
|
||||
|
||||
sandwich:
|
||||
@if [ `id -u` -eq 0 ]; then \
|
||||
echo 'Okay.'; \
|
||||
echo $${RANDOM}`date +%s`$${RANDOM} > $@; \
|
||||
else \
|
||||
echo 'What? Make it yourself.'; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
# Understand the history of the Homebrew Computer Club
|
||||
# as well as the West Coast Computer Faire and
|
||||
# you might be confused different. :-)
|
||||
#
|
||||
supernova: nuke
|
||||
@-if [ -r .code_anal ]; then \
|
||||
${RM} -f .code_anal_v6; \
|
||||
else \
|
||||
echo "planet deniers, like some members of the IAU, are so cute when they try to defend their logic"; \
|
||||
fi
|
||||
@echo A $@ helps ${MAKE} the elements that help form planets
|
||||
@${TRUE}
|
||||
|
||||
deep_magic:
|
||||
@-if [ -r .code_anal ]; then \
|
||||
ccode_analysis --deep_magic 3a3fabb90892eeb2f610ae0f74a35a970060665a063ab702bd686c17c4ae07f6 --FNV1a_hash_256_bit "prog"; \
|
||||
else \
|
||||
echo "Wrong! Do it again!"; \
|
||||
sleep 2; \
|
||||
echo "Wrong! Do it again!"; \
|
||||
sleep 2; \
|
||||
echo "Wrong! Do it again!"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
|
||||
magic: deep_magic
|
||||
@-if [ -r .code_anal ]; then \
|
||||
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_256_bit "prog"; \
|
||||
else \
|
||||
echo "If you don't eat yer meat, you can't have any pudding!"; \
|
||||
echo "How can you have any pudding if you don't eat yer meat?!"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
|
||||
# The IOCCC resident astronomer states
|
||||
#
|
||||
charon: supernova
|
||||
@echo $@ is a dwarf planet
|
||||
@echo dwarf is a type of planet
|
||||
@echo $@ is a planet
|
||||
|
||||
pluto: supernova
|
||||
${MAKE} charon
|
||||
@echo $@ is a dwarf planet
|
||||
@echo dwarf is a type of planet
|
||||
@echo $@ is a planet
|
||||
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
|
||||
@@ -0,0 +1,88 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
|
||||
<link rel="stylesheet"
|
||||
type="text/css"
|
||||
href="../hint.css">
|
||||
<title>Best use of python</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Best use of python</h1>
|
||||
|
||||
<p>Yusuke Endoh<br>
|
||||
Twitter: @mametter</p>
|
||||
|
||||
<h2>Judges' comments:</h2>
|
||||
|
||||
<h3>To use:</h3>
|
||||
|
||||
<pre><code>make
|
||||
|
||||
./prog
|
||||
</code></pre>
|
||||
|
||||
<h3>Try:</h3>
|
||||
|
||||
<pre><code>make
|
||||
|
||||
./prog | tee prog_next.c
|
||||
make prog_next
|
||||
./prog_next | tee prog_next.c
|
||||
make prog_next
|
||||
./prog_next | tee prog_next.c
|
||||
|
||||
make python
|
||||
|
||||
make python3
|
||||
</code></pre>
|
||||
|
||||
<h3>Selected Judges Remarks:</h3>
|
||||
|
||||
<p>And now for something completely different: A program whose metabolic
|
||||
processes are a matter of interest only to historians. It has kicked the bucket
|
||||
and departed to that mysterious country from whose bourne no traveller returns!
|
||||
This is an EX-tremely obfuscated program!</p>
|
||||
|
||||
<h2>Author’s comments:</h2>
|
||||
|
||||
<pre><code> ___-----__
|
||||
_-- --__
|
||||
_- _--_ \
|
||||
_- /\ +-.:.:-+ /\ \
|
||||
/ \/ |.:.:.:| \/ |
|
||||
/ |:.:.:.| |
|
||||
/ |.:.:.:| | ___-----___
|
||||
| |.:.:| | / \
|
||||
| |:.:.| | < It's ... |
|
||||
\ |:.| | \ /
|
||||
\ || | ---_____---
|
||||
_--\ |
|
||||
_- -__ |
|
||||
__- --___ |
|
||||
_- |
|
||||
/ |
|
||||
| |
|
||||
</code></pre>
|
||||
|
||||
<hr />
|
||||
|
||||
<!--
|
||||
(c) Copyright 1984-2018, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
|
||||
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
|
||||
|
||||
[judges]: http://www.ioccc.org/judges.html
|
||||
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
-->
|
||||
|
||||
<TABLE><TR>
|
||||
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
|
||||
<TD><P>© Copyright 1984-2018,
|
||||
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
|
||||
- All rights reserved<BR>
|
||||
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
|
||||
<TD> <!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
|
||||
</TR></TABLE>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,62 @@
|
||||
# Best use of python
|
||||
|
||||
Yusuke Endoh
|
||||
Twitter: @mametter
|
||||
|
||||
|
||||
## Judges' comments:
|
||||
### To use:
|
||||
|
||||
make
|
||||
|
||||
./prog
|
||||
|
||||
### Try:
|
||||
|
||||
make
|
||||
|
||||
./prog | tee prog_next.c
|
||||
make prog_next
|
||||
./prog_next | tee prog_next.c
|
||||
make prog_next
|
||||
./prog_next | tee prog_next.c
|
||||
|
||||
make python
|
||||
|
||||
make python3
|
||||
|
||||
### Selected Judges Remarks:
|
||||
|
||||
And now for something completely different: A program whose metabolic
|
||||
processes are a matter of interest only to historians. It has kicked the bucket
|
||||
and departed to that mysterious country from whose bourne no traveller returns!
|
||||
This is an EX-tremely obfuscated program!
|
||||
|
||||
|
||||
## Author's comments:
|
||||
___-----__
|
||||
_-- --__
|
||||
_- _--_ \
|
||||
_- /\ +-.:.:-+ /\ \
|
||||
/ \/ |.:.:.:| \/ |
|
||||
/ |:.:.:.| |
|
||||
/ |.:.:.:| | ___-----___
|
||||
| |.:.:| | / \
|
||||
| |:.:.| | < It's ... |
|
||||
\ |:.| | \ /
|
||||
\ || | ---_____---
|
||||
_--\ |
|
||||
_- -__ |
|
||||
__- --___ |
|
||||
_- |
|
||||
/ |
|
||||
| |
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
<!--
|
||||
(c) Copyright 1984-2018, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
|
||||
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
|
||||
|
||||
[judges]: http://www.ioccc.org/judges.html
|
||||
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
-->
|
||||
@@ -0,0 +1,32 @@
|
||||
|
||||
#define/**/Q( q)int*P,t,u,M [99999], *S=3557\
|
||||
+M,*C=M+3800; char*Q=#q;int (main) (){q;}
|
||||
# include <stdio.h> /*IOC CCC*/
|
||||
Q(for(;* Q>34?(*S ++=*Q ++):*
|
||||
(Q+= *Q- 27?1:Q[2 ]/49+ 4);); for ( S=M+9 ;*C;u =t%9,t <18?*
|
||||
++S=t<0? *C++%92* 57-t-500:t<9?M[u]:M [u]++:t<27?M[u ]=*S--:u?t=* S--,u<2?M[t]=*S--:u< 3?C+=*S--?t:0,
|
||||
0:u-6?*S =u<4?*S- t:u/*ABCDEFGH*/<5?* S%t:*S<t:putchar (t):(*S=M[*S]))t =*C++-93;return+0**" Ler[Tsaxiyj.V}<\
|
||||
dzSGs`Fk {YezYTtb x0d{iy kNT}?d zaxiyjE K}TdzHe iy`Me{ Tf|)dz HeiyH eiyjxiyax Ldz2sx Ke{'d\
|
||||
|Yd{2sy? [saY^{tG erjxuj xvbqax` {)dzc kydj/ dzjxkya_}JdziHf}Ydz -Vw2d rQ)qJe_y h@*}<d zHeh\
|
||||
yAehy)*n x{qnxKe{ Df|Qd{ uc)e{& dzZfh yCehy 6fuchyex;e{ZdzIe_yn q1dqD +u/dcyl5 L}<dzL IETi\
|
||||
{x=b{1g|{uc2d{byaxvcDfd }&dzDVd {x6ecOe z1dcydCf_{{)d|qSf2 T_{x$c{ ;g|{{u Ffjx}4czb q_xucx/d }Jez0dly\
|
||||
c/d{hycSf{hychycFc{ hy_)Ic}{q _0d{qb_}.c z:eo:T`{xp]q1d`{D` zD+ulxcx{-dzcCez 7evOe~Hf~0dcx}/dzd~cx x~6f~m6e0dcx}{}Ud\
|
||||
zc(*{x~c0d{Tf |.dz'd~c5 L}Ecz1d[Ty /*0+)IFMNFU*+0- 02;>@=,(#155 5546231rst%wvu#08OCC C*/#include/*#"
|
||||
|
||||
|
||||
|
||||
"exclude*/<stdio. h>#def\
|
||||
ine/**/Q(q)int*P,t,u,M[ 99999],\
|
||||
*S=3557+M,*C=M+3800;cha r*Q=#\
|
||||
q;int(ma in)(){q;} Q(@@~c\
|
||||
d`c/C@~o `rrdc~n m/GSghr~o`qqns~hr~\
|
||||
mn~lnqd/ FH~g`ud~ bd`rdc~sn~a d/O@~dw ohqdc~`mc~fnmd~sn~ ldds~lx~l`jdq/GSgh r~hr~`~k`sd ~o`qqns/LAdqdes~ne\
|
||||
~khed+~H~qdrs~hm~od`bd /KH&c~ad~otrghmf~to~s gd~c`hrhdr/X@~qtm~cn vm~sgd~btqs`hm~`mc~i nhmdc~sgd~bgnhq~ hmuhr\
|
||||
hakd/FSghr~hr~`m~dw, o`qqns /6Zba4ORRZ T`]Sa` fdgO2bPV[ Ta5dT[ MVfbZZHY b79bVT^ :L;S<J= X>Q?X\
|
||||
@SAZBWCIDNEQF`GXPU UgW^a a[bIaZ[Z afaf_` Kg`ZYY[ [`gff^ Jg``8OK KT,VNa6 /TZSW` 0cRMWO 3\
|
||||
3f][T`-[K aV,[Z /6aPWLab f[P[a3 f`0dPR `3M3]8/ R[Z-Z, VZR#MR TfNTT\
|
||||
4d5^$S]8 RMKRVa MM8T$9aaZ gaRSg1 NZ1`5^ d`LK]. %&VZ,' R#gKaZ f1T\
|
||||
T10aa`b].TZ- KK/28`-6VKf'ZH^P(./Ka8 a)8[O6NaTb f*[Hd+Z(V 8&3K%)VNTR#&WbX[ H^dcOWOf]8[OR[aT\
|
||||
OM2V'$9aLR[RW* `0+OMW[([14ZLaK%).NO6 RMRS*[0+ZO WZS]_<<<< <htt"/*pa*/"p: //"/*x@*/"cult\
|
||||
ofthepartypa rrot.co m/>>>> >__<-_So urce_of_P arrots __(")
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
# Do the compile and run loop for 10 seconds
|
||||
|
||||
transient_parrot=$(tempfile -s .c)
|
||||
cp prog.c "$transient_parrot"
|
||||
|
||||
stop_dancing_deadline=$(($(date +"%s")+10))
|
||||
while [[ $(date +"%s") -lt "$stop_dancing_deadline" ]]; do
|
||||
gcc "$transient_parrot" -o ./prog && ./prog | tee "$transient_parrot"
|
||||
sleep 0.01
|
||||
done
|
||||
|
||||
rm -f "$transient_parrot"
|
||||
@@ -0,0 +1,94 @@
|
||||
This file is a brief description of the files in this entry.
|
||||
|
||||
|
||||
prog.c This is the source file to the `weasel'
|
||||
program [1].
|
||||
|
||||
|
||||
prog-simple.c This is the source code file to the
|
||||
`weasel-simple' program [1].
|
||||
|
||||
|
||||
test.sh Script provided to test the weasel program [1].
|
||||
|
||||
|
||||
test-strings.txt The test.sh script reads from this file and runs
|
||||
the weasel program for each line read.
|
||||
|
||||
|
||||
Makefile The Makefile that simplifies compilation as well as
|
||||
providing some deep magic and other things designed
|
||||
by the IOCCC judges. There's also a `make test'
|
||||
target that runs the 'test.sh' script. The hint
|
||||
file shows how to pass options to the script
|
||||
itself [1].
|
||||
|
||||
|
||||
weasel.man The local version of the man page; that is if it's
|
||||
not installed. You can still use 'man' on the
|
||||
'weasel.1' file but 'weasel.man' references
|
||||
different file paths from 'weasel.1'.
|
||||
|
||||
|
||||
weasel.1 The system wide version of the man page for when
|
||||
(if) it's installed [2]. Note that the suggested
|
||||
invocation 'man -l ./weasel.man' can be replaced
|
||||
with 'man -l ./weasel.1' too but if the weasel
|
||||
package is installed 'man weasel.1' (note the
|
||||
missing '-l ./') would read the from the system
|
||||
man page.
|
||||
|
||||
|
||||
|
||||
hint.text The source of the hint.html file [3].
|
||||
hint.txt 'hint.txt' is a possible name in the future
|
||||
according to the judges.
|
||||
|
||||
|
||||
hint.html More thorough documentation including example
|
||||
invocations, how to compile, final and winning
|
||||
thoughts, some of the obfuscation techniques that
|
||||
might be used, etc. [3].
|
||||
|
||||
|
||||
hint.css The CSS file for the hint.html file [3].
|
||||
|
||||
|
||||
rpm.markdown This file briefly answers 'why' I submitted a rpm
|
||||
spec file 'weasel.spec' as well as the possibility
|
||||
of building the RPM for others (despite the fact I
|
||||
am confident that I'm the only one who would make
|
||||
use of it). This file isn't included in the RPM
|
||||
itself; it remains only on the IOCCC website.
|
||||
|
||||
|
||||
weasel.spec The RPM spec file for building the RPM. This is
|
||||
specific to the entry on the IOCCC website but
|
||||
would also be available in the source rpm file if
|
||||
it was built.
|
||||
|
||||
|
||||
FILES If you want a brief description of the FILES file
|
||||
(this file) then read this file (the file FILES).
|
||||
|
||||
|
||||
|
||||
* Footnotes
|
||||
|
||||
The follow footnotes are for if the weasel program is installed into the
|
||||
system. As I noted before it was primarily personal reasons that I submitted
|
||||
the spec file. Please note that the paths below are dependent on the prefix
|
||||
used in installation; where I suggest '/usr' it is equally possible it could be
|
||||
under '/usr/local', for example.
|
||||
|
||||
[1] Note that 'prog.c' and 'prog-simple.c' would be
|
||||
linked to 'weasel.c' and 'weasel-simple.c'
|
||||
(respectively) in the '/usr/src/weasel'
|
||||
subdirectory.
|
||||
|
||||
[2] The file would most likely be compressed as
|
||||
'weasel.1.gz' under the '/usr/share/man/man1'
|
||||
subdirectory.
|
||||
|
||||
[3] These files would be in the
|
||||
'/usr/share/doc/weasel' subdirectory.
|
||||
Loaded 100 of 1683 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user