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
@@ -0,0 +1,212 @@
|
||||
#!/usr/bin/env make
|
||||
#
|
||||
# 2013 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
|
||||
LD= ld
|
||||
MAKE= make
|
||||
RM= rm
|
||||
SED= sed
|
||||
TAR= tar
|
||||
TRUE= true
|
||||
|
||||
# Set X11_LIBDIR to the directory where the X11 library resides
|
||||
#
|
||||
X11_LIBDIR= /usr/X11R6/lib
|
||||
|
||||
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
|
||||
#
|
||||
X11_INCDIR= /usr/X11R6/include
|
||||
|
||||
# Compiler warnings
|
||||
#
|
||||
#CWARN=
|
||||
CWARN= -Wall
|
||||
#CWARN= -Wall -pedantic
|
||||
|
||||
# compiler standard
|
||||
#
|
||||
#CSTD=
|
||||
#CSTD= -ansi
|
||||
CSTD= -std=c99
|
||||
|
||||
# compiler bit architecture
|
||||
#
|
||||
# Some entries require 32-bitness:
|
||||
# ARCH= -m32
|
||||
#
|
||||
# Some entries require 64-bitess:
|
||||
# ARCH= -m64
|
||||
#
|
||||
# By default we assume nothing:
|
||||
#
|
||||
ARCH=
|
||||
|
||||
# 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.
|
||||
#
|
||||
#OPT=
|
||||
#OPT= -O
|
||||
#OPT= -O1
|
||||
OPT= -O2
|
||||
#OPT= -O3
|
||||
|
||||
# Libraries needed to build
|
||||
#
|
||||
LIBS=-lm
|
||||
|
||||
# default flags for ANSI C compilation
|
||||
#
|
||||
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${OPT}
|
||||
|
||||
# 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
|
||||
##############################
|
||||
#
|
||||
ENTRY= hou
|
||||
OTHER_PROG= a
|
||||
OTHER_SRC= a.c
|
||||
OTHER_OBJ= a.o
|
||||
DATA=
|
||||
ALT_OBJ=
|
||||
ALT_ENTRY=
|
||||
|
||||
|
||||
#################
|
||||
# build the entry
|
||||
#################
|
||||
#
|
||||
all: ${ENTRY} ${DATA}
|
||||
@${TRUE}
|
||||
|
||||
${OTHER_PROG}: ${ENTRY}.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
${OTHER_SRC}: ${OTHER_PROG}
|
||||
${RM} -f $@
|
||||
./${OTHER_PROG} > $@
|
||||
|
||||
${ENTRY}: ${OTHER_SRC}
|
||||
${CC} ${CFLAGS} $< -o $@ ${LIBS}
|
||||
|
||||
# alternative executable
|
||||
#
|
||||
alt: ${ALT_ENTRY}
|
||||
@${TRUE}
|
||||
|
||||
# data files
|
||||
#
|
||||
data: ${DATA}
|
||||
@${TRUE}
|
||||
|
||||
|
||||
###############
|
||||
# utility rules
|
||||
###############
|
||||
#
|
||||
everything: all alt
|
||||
|
||||
clean:
|
||||
${RM} -f ${ENTRY}.o ${OTHER_OBJ} ${ALT_OBJ}
|
||||
|
||||
clobber: clean
|
||||
${RM} -f ${ENTRY} ${OTHER_SRC} ${OTHER_PROG} ${ALT_ENTRY}
|
||||
|
||||
nuke: clobber
|
||||
@${TRUE}
|
||||
|
||||
dist_clean: nuke
|
||||
@${TRUE}
|
||||
|
||||
install:
|
||||
@echo "Surely we are joking Dr. Lehmer!"
|
||||
@${TRUE}
|
||||
|
||||
# backwards compatibility
|
||||
#
|
||||
build: all
|
||||
@${TRUE}
|
||||
|
||||
|
||||
##################
|
||||
# 133t hacker rulz
|
||||
##################
|
||||
#
|
||||
love:
|
||||
@echo 'not war?'
|
||||
@${TRUE}
|
||||
|
||||
haste:
|
||||
$(MAKE) waste
|
||||
@${TRUE}
|
||||
|
||||
waste:
|
||||
@echo 'haste'
|
||||
@${TRUE}
|
||||
|
||||
easter_egg:
|
||||
@echo you expected to mis-understand this $${RANDOM} magic
|
||||
@echo chongo '<was here>' "/\\oo/\\"
|
||||
@echo Readers shall not be disallowed from being unable to not partly misunderstand this partocular final echo.
|
||||
|
||||
# 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_v4; \
|
||||
else \
|
||||
echo "We are not expected to understand that"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
|
||||
deep_magic:
|
||||
@-if [ -r .code_anal ]; then \
|
||||
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash 512-bit "${ENTRY}"; \
|
||||
else \
|
||||
echo "Park different"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
|
||||
magic: deep_magic
|
||||
@-if [ -r .code_anal ]; then \
|
||||
ccode_analysis --mode 391581 --level 216193 --FNV1a_hash 512-bit "${ENTRY}"; \
|
||||
else \
|
||||
echo "These aren't the primes you're looking for Paul Erdos!"; \
|
||||
fi
|
||||
@${TRUE}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 7.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.5 KiB |
@@ -0,0 +1,352 @@
|
||||
|
||||
# Scene format documentation
|
||||
|
||||
This file is encoded in UTF-8 as the BOF marker indicates.
|
||||
|
||||
You can directly feed it to the renderer. If you're wondering about what the following code block does, that's why:)
|
||||
|
||||
@|?|?z#
|
||||
@|||?z&
|
||||
>?Sedvf
|
||||
??Tdeu#
|
||||
>>Tdeui
|
||||
??Tdmmf
|
||||
??[[euf
|
||||
?}?Oq}e
|
||||
?}?Oqqf
|
||||
v}?|q}e
|
||||
v}?|qqf
|
||||
?Sj|?{f
|
||||
?Tjk?{e
|
||||
FF?Oqq$
|
||||
RR?Oqq$
|
||||
^^?Oqq$
|
||||
jj?Oqq$
|
||||
vv?|qq$
|
||||
IOBMqqe
|
||||
U]BMqqe
|
||||
aiBMqqe
|
||||
muBMqqe
|
||||
EEEJpp%
|
||||
QQEJpp%
|
||||
]]EJpp%
|
||||
iiEJpp%
|
||||
uuEJpp%
|
||||
ZnY|{|e
|
||||
[mZ|{{#
|
||||
[mZ|||f
|
||||
kkdr{{%
|
||||
lkdr{{>
|
||||
|
||||
|
||||
## Basic structure
|
||||
|
||||
A scene file begins with arbitrary binary data, followed by several shader functions.
|
||||
|
||||
Shader functions are declared using a one-character name followed by a ']' character. There are some special function names, which will be explained below.
|
||||
|
||||
The language used to write shader functions is very simple. Basically, you write a sequence of assignment statements like this:
|
||||
A=A+D
|
||||
B=B+E
|
||||
Namely, you write a one-character variable name, an equal sign '=', followed by an expression (made of operators and one-character variable names, of course).
|
||||
|
||||
## Expressions
|
||||
|
||||
The shader language supports seven operators, listed highest priority first:
|
||||
*/+-<#:
|
||||
|
||||
`*/+-<` mean what they mean in C, but the priority part is a bit different. Basically, `*` has higher priority than `/`, so `A/4*4` actually computes `A/(4*4)`. And you can't write `(A/4)*4` -- brackets are not supported. As an advice, keep your expressions simple :) If you really needs to write something like C=(A/4)*4, write instead:
|
||||
B=A/4+
|
||||
C=B*4
|
||||
|
||||
The # operator acts somewhat like the C ?:. It returns one of its two operands based on, what else, the value of variable #. When # is true, # returns its second operand.
|
||||
|
||||
The : operator calls built-in functions. The first operand is the function id and the second is the parameter. Here is a list of functions:
|
||||
0:x = the x-th byte of the scene file
|
||||
1:x = sin(x*PI)
|
||||
2:x = atan2(x,#)/PI
|
||||
3:x = sqrt(max(x,0))
|
||||
4:x = floor(x)
|
||||
5:x = the next number in the (allegedly random) number sequence, can't be called in volume shaders
|
||||
6:x = value of the variable (char)(120+x)
|
||||
7:x = write #'s value to the variable (char)(120+x)
|
||||
|
||||
Contrary to popular belief, the language itself doesn't support numerical constants. Any character sitting between operators is a variable. When you see 1/2, it's in fact dividing the variable 1's value by the variable 2's value. For everyone's convenience, though, in the beginning every variable is initialized to its ASCII code minus 48. As long as you don't write something like 3=1+1, you can use single digit numbers as, well, single digit numbers. If you need something like 1920 or 0.73, you need to compute it yourself. And yes, all variables store floating point values.
|
||||
|
||||
If a character appears as the first character of any argv, it goes to zero. This includes the scene filename. If you name your scene '1.scene', well, good luck with 1=0!
|
||||
|
||||
You can terminate a statement using any character that isn't an operator, be it \n or ;. But you must put in one and only one character. Put in two (e.g. the Windows \r\n), and it terminates your function. Also, the first statement must begin immediately after ']'.
|
||||
|
||||
When a function terminates, the interpreter calls the next function specified by variable R. If you want to call function 'n', just write somewhere:
|
||||
R=n
|
||||
providing you have left n at its initial value. If you want to actually return to the renderer, put in R=0.
|
||||
|
||||
As you may have noticed, you can put in all kinds of stuff between functions, like this comment.
|
||||
|
||||
## How the ____ do I render an image with shaders?
|
||||
|
||||
Basically, you define a geometry using volume shaders, define a camera using a camera shader, and define light sources and surface reflectance properties using material shaders.
|
||||
|
||||
-------------------------------------------
|
||||
Continue to the comments before function A
|
||||
-------------------------------------------
|
||||
|
||||
//As an (optional) assignment, figure out what function `n` does. And why there is a plus sign at every EOL except the last.
|
||||
n]#=1+
|
||||
x=X+1/2+
|
||||
d=0:U;d=d-n;U=U+1;A=d<x;#=#*A+
|
||||
d=0:U;d=d-n;U=U+1;A=x<d+1;#=#*A+
|
||||
x=Y+1/2+
|
||||
d=0:U;d=d-n;U=U+1;A=d<x;#=#*A+
|
||||
d=0:U;d=d-n;U=U+1;A=x<d+1;#=#*A+
|
||||
x=Z+1/2+
|
||||
d=0:U;d=d-n;U=U+1;A=d<x;#=#*A+
|
||||
d=0:U;d=d-n;U=U+1;A=x<d+1;#=#*A+
|
||||
d=0:U;d=d-n;U=U+1+
|
||||
U=U+2+
|
||||
C=C#d+3*9+
|
||||
#=d+
|
||||
R=0#n
|
||||
|
||||
-------------------------------------------
|
||||
|
||||
The function "A" initializes global settings:
|
||||
G -- Image width, in pixels
|
||||
H -- Image height, in pixels
|
||||
I -- Perturbation probability
|
||||
J -- Camera ray stratification probability
|
||||
If you have used a MLT renderer before, you probably know what I and J does. If you don't, well, use the same value as the default scene. Everything converges just fine under suboptimal settings, just a little slower. Generally, use a higher value for I if your scene is primarily illuminated by some indirect source.
|
||||
|
||||
"A" also serves as the geometry shader for volume 0. The scene geometry is made of up to 32 volumes, each with 64x64x64 cells. The volume 0 is the 'top level' volume where the camera goes. Each cell of a volume can be empty, filled with a material, or another volume. The round-ish characters in old_default.scene and the carpet on the floor in this file are examples where a cell is defined to another volume. Materials will be explained later.
|
||||
|
||||
The volume shader for the i-th volume is named as the (i+1)-th capital letter. Each volume shader is invoked once for each cell. The cell coordinates (0..63) are given as inputs in variable x,y,z, and you're supposed to return the cell content in variable C. To fill it with material i, return 64+i in C. To fill it with volume i, well, return i. To leave it empty, return C=0.
|
||||
|
||||
Before starting to build a scene, it's better to have a draft sketch handy first. Something like . Sometimes it's hard to imagine where something should go without the sketch. And you don't have to stick to your sketch :)
|
||||
|
||||
What motivated my default scene: it was the full moon's day (a national holiday) in China and my parents were planning to renovate their apartment. I rendered the image to tell my mom how ridiculous her starry-sky wall paper would look like if she used it on every single wall. She ends up using it on just one wall, the one facing my bed, to thank me for the effort.
|
||||
|
||||
-------------------------------------------
|
||||
Continue to the comments before function a
|
||||
-------------------------------------------
|
||||
|
||||
//As a bonus, find out what the first line does
|
||||
A]#=#-#;"=7:0-p+^;#="+
|
||||
R=n+
|
||||
G=p*:+
|
||||
#=0<B+
|
||||
G=G*2#G+
|
||||
H=G*3/4+
|
||||
I=4/5+
|
||||
J=1/2+
|
||||
C=p+1+
|
||||
U=w+w+w
|
||||
|
||||
-------------------------------------------
|
||||
|
||||
The function 'a' is the camera shader, which, well, generates the camera ray. It's supposed to return the ray in variables UVWXYZ and ABCDEF (that may sound like a lot of variables, but it really isn't that much).
|
||||
|
||||
Here comes some subtlety of PSSMLT (Primary Sample Space Metropolis Light Transport, or Kelemen-style MLT). Basically, a PSSMLT renderer gives you an (allegedly random) number sequence, and you compute a color out of it. This is usually done by generating and tracing rays out of those random numbers. The renderer would assemble the colors into an image.
|
||||
|
||||
Remember the function 5? Here it comes. The first two "random" numbers have special meaning and must specify a point on the image plane [0,1)x[0,1). You're supposed to transform the image plane to the 3D space, choose a point for the camera, and shoot a ray from the camera point to the image plane point, see . The camera point goes to (U,V,W), and the ray direction vector (image plane point - camera point) is (X,Y,Z). For the coordinate space, volume 0 is scaled up 64x here to (0,0,0)-(4096,4096,4096).
|
||||
|
||||
For a basic camera shader example, check "otherroom.scene".
|
||||
|
||||
If any ray goes out of volume 0, the renderer crashes. Make sure it doesn't happen. Wall up everything.
|
||||
|
||||
Variables ABCDEF control the color returned from the ray. They will be explained in the material shaders part. For now, just put in:
|
||||
A=0;B=0;C=0
|
||||
D=1;E=1;F=1
|
||||
|
||||
-------------------------------------------
|
||||
Continue to the comments before function 1
|
||||
-------------------------------------------
|
||||
|
||||
a]R=0+
|
||||
X=5:5+
|
||||
Y=5:5+
|
||||
X=X-1/2+
|
||||
Y=Y-1/2+
|
||||
x=5:5+
|
||||
y=5:5+
|
||||
x=x-1/2+
|
||||
y=y-1/2+
|
||||
x=x*8*7;y=y*8*7+
|
||||
X=X*G+
|
||||
Y=Y*H+
|
||||
Z=H*2/3+
|
||||
d=4*;+
|
||||
d=d*p/Z+
|
||||
X=x+X*d+
|
||||
Y=y+Y*d+
|
||||
Z=Z*d+
|
||||
U=p*p/2-p*2+x+
|
||||
V=p*p/2+p*1-y+
|
||||
W=p*8+
|
||||
A=0;B=0;C=0+
|
||||
D=1;E=1;F=1
|
||||
|
||||
--------------------------------------------------------
|
||||
|
||||
The numbered functions define materials, i.e., surface reflectance properties. As the name suggests, the shader simulates ray-surface interaction. It's done by updating UVWXYZABCDEF, of course.
|
||||
|
||||
ABCDEF define colors. (A,B,C) is the RGB irradiance ultimately returned to the renderer, and (D,E,F) maintains the cumulative RGB reflectance of the current ray path. This may sound confusing, but basically, if the surface is a light source, you accumulate the current path reflectance (D,E,F), multiplied by the light strength, to (A,B,C). See shader 6 for an example.
|
||||
|
||||
If you want a colored surface, use its color to modulate (D,E,F), i.e. D=D*red;E=E*green;F=F*blue, easy as that. To get some texturing, compute the color procedurally or look up a binary table.
|
||||
|
||||
There's something subtle about colors. To go along with the trend, the renderer follows the practice of linear rendering with a gamma of 2. Stripping the fancy jargons, that basically means after picking a color in your favorite image editing program, you need to convert the RGB values from 0..255 to 0..1, and then put here its *square*. Only after squaring you get your real, lively color in the output image, as opposed to something dull and gray. You need to do the same if you use a RGB texture. And yes, that is the what the second sqrt in a.c is for.
|
||||
|
||||
Going beyond colors, to define a shiny or dull surface one needs more maths, and optics. The jargon for this is BRDF (Bidirectional Reflectance Distribution Function) importance sampling. Let's continue to function o.
|
||||
|
||||
-------------------------------------------
|
||||
Continue to the comments before function o
|
||||
-------------------------------------------
|
||||
|
||||
//This function computes the starred wallpaper
|
||||
//Original color: 0.36 0.714285 0.8
|
||||
1]R=o+
|
||||
d=p*6+
|
||||
x=U+W+
|
||||
x=4:x/d+
|
||||
z=4:V/d+
|
||||
#=3*x-4*z+
|
||||
y=4:#/5+
|
||||
#=#-y*5+
|
||||
y=1#0+
|
||||
x=x*d+d/2-U+W+
|
||||
z=z*d+d/2-V+
|
||||
r=3:x*x+z*z+
|
||||
#=z+
|
||||
u=2:x+
|
||||
d=1:u*5+
|
||||
d=d*d*d+3/2+
|
||||
d=d*p+
|
||||
#=r<d+
|
||||
#=#*y+
|
||||
d=2/5#I+
|
||||
D=D*d+
|
||||
E=E*4/7+
|
||||
d=I#2/5+
|
||||
F=F*d
|
||||
|
||||
-------------------------------------------
|
||||
|
||||
Function o defines a diffuse (that is, dull) surface. To define reflectance properties like this, one needs to sample an outgoing ray direction, based on the incoming direction and the surface normal. It's called importance sampling, because here the probability of each outgoing direction has to be proportional to the reflected light strength (i.e., the BRDF) on that direction. For a diffuse surface, sample the upper hemisphere with a probability proportional to the cosine of the outgoing angle, see .
|
||||
|
||||
The incoming direction is in (X,Y,Z) and the hit point is (U,V,W). The outgoing direction is returned in, where else, (X,Y,Z).
|
||||
|
||||
The surface normal is provided in variables S and T. Since the geometry is defined as a bunch of cube-shaped cells, there are only 6 possible normals: (±1,0,0) (0,±1,0) (0,0,±1). Here S is the sign and T is the dimension. If you get S=-1 and T=1, the normal is (0,-1,0).
|
||||
|
||||
If you don't want to redo all the math yourself... this file provides a few simple shader functions:
|
||||
o -- Diffuse surface. Do the color thing your self and call R=o
|
||||
5 -- Perfect mirror.
|
||||
f -- Surface with a Fresnel term. Basically, it resembles a polished surface made from a dielectric material.
|
||||
|
||||
For something more complex like a fluffy carpet, well, you could use a volume to directly model the mesoscopic detail. Shader D in this file produces a bunch of dense, tiny spikes to simulate a fluffy appearance.
|
||||
|
||||
-------------------------------------------
|
||||
Continue to the EOF
|
||||
-------------------------------------------
|
||||
|
||||
//diffuse ray generation
|
||||
o]R=0+
|
||||
u=5:5+
|
||||
v=5:5+
|
||||
v=v*2+
|
||||
r=3:u+
|
||||
z=1:v+
|
||||
y=1:1/2+v+
|
||||
z=z*r+
|
||||
y=y*r+
|
||||
x=3:1-u+
|
||||
x=0-x*S+
|
||||
X=6:T+
|
||||
w=x;x=z;z=y;y=w+
|
||||
Y=6:T+
|
||||
w=x;x=z;z=y;y=w+
|
||||
Z=6:T
|
||||
|
||||
//reflector
|
||||
5]R=0+
|
||||
x=1;y=1;z=1+
|
||||
#=0-1+
|
||||
#=7:T+
|
||||
X=x*X;Y=y*Y;Z=z*Z
|
||||
|
||||
//approximate Fresnel, works better than the real thing when you don't want to tweak the IOR
|
||||
f]x=X;y=Y;z=Z+
|
||||
r=3:x*x+z*z+y*y+
|
||||
d=6:T+
|
||||
d=1-d*S/r+
|
||||
d=d*d*d+
|
||||
#=5:5+
|
||||
#=d<#+
|
||||
R=5#o+
|
||||
d=d#1-d+
|
||||
u=1#u+
|
||||
v=1#v+
|
||||
w=1#w+
|
||||
D=D*d*u+
|
||||
E=E*d*v+
|
||||
F=F*d*w
|
||||
|
||||
//the handles
|
||||
B]R=0+
|
||||
#=X<8*3+
|
||||
C=3#0
|
||||
|
||||
C]R=0+
|
||||
#=X<8*4+
|
||||
C=0#4
|
||||
|
||||
//red-Fresnel
|
||||
2]R=f+
|
||||
u=1/2;v=1/9;w=v
|
||||
|
||||
//white-Fresnel and the full moon
|
||||
3]R=f+
|
||||
u=7*9/p;v=u;w=v+
|
||||
x=3*:+8+
|
||||
z=U-x*p+p/2+
|
||||
x=V-x*p-p/2+
|
||||
r=3:x*x+z*z+
|
||||
#=4<r/p+
|
||||
D=D*I#D+
|
||||
E=E*4/7#E+
|
||||
F=F*2/5#F+
|
||||
d=1/5#0+
|
||||
A=A+D*d+
|
||||
B=B+E*d+
|
||||
C=C+F*d
|
||||
|
||||
//handle
|
||||
4]R=5+
|
||||
D=D*I;E=E*4/7;F=F*2/5
|
||||
|
||||
//light from the window
|
||||
6]R=0+
|
||||
#=P+
|
||||
d=2#8*2+
|
||||
A=A+D*d+
|
||||
B=B+E*d+
|
||||
C=C+F*d*I+
|
||||
P=9
|
||||
|
||||
//carpet
|
||||
7]R=o+
|
||||
D=D/7+
|
||||
E=E/3+
|
||||
F=F/7
|
||||
|
||||
D]R=0+
|
||||
#=8<Y+
|
||||
C=0#3+
|
||||
#=4:3*X-4*Z+
|
||||
y=4:#/7+
|
||||
#=#-y*7+
|
||||
C=7#C
|
||||
|
||||
-------------------------------------------
|
||||
|
||||
The last line, well, is the output filename. Just remember to throw in two ']'s and don't put a newline after it.
|
||||
|
||||
]]example.ppm
|
||||
@@ -0,0 +1,150 @@
|
||||
<!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 1 Infinite Loop</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Best use of 1 Infinite Loop</h1>
|
||||
|
||||
<p>Qiming Hou<br>
|
||||
<a href="mailto:hqm03ster@gmail.com">hqm03ster@gmail.com</a><br>
|
||||
<a href="http://www.houqiming.net">http://www.houqiming.net</a></p>
|
||||
|
||||
<h2>Judges' comments:</h2>
|
||||
|
||||
<h3>To build:</h3>
|
||||
|
||||
<pre><code>make hou
|
||||
</code></pre>
|
||||
|
||||
<h3>To run:</h3>
|
||||
|
||||
<pre><code>./hou [scene-file-name] [options]
|
||||
|
||||
Follow the instructions in stdout, preferably with an auto-refreshing PPM image viewer ready.
|
||||
Refresh the image every time the output refreshes, all effects should be more or less recognizable when you see 16.
|
||||
</code></pre>
|
||||
|
||||
<h3>Try:</h3>
|
||||
|
||||
<pre><code>./hou BIG
|
||||
./hou old_default.scene BIG
|
||||
./hou otherroom.scene
|
||||
./hou otherroom.scene NAIVE
|
||||
</code></pre>
|
||||
|
||||
<h3>Selected Judges Remarks:</h3>
|
||||
|
||||
<p>You could consider that this program violates the source code size
|
||||
limit. This is because the first compliation of this program is
|
||||
really just a decompressor to generate the real source code of the
|
||||
program.</p>
|
||||
|
||||
<p>This program will loop infinitely while progressivly refining a
|
||||
raytraced image.</p>
|
||||
|
||||
<h2>Author’s comments:</h2>
|
||||
|
||||
<h3>Using hou</h3>
|
||||
|
||||
<p>This program is a programmable rendering engine with a built-in default scene. The standard command line is:</p>
|
||||
|
||||
<pre><code>./hou [scene-file-name] [options]
|
||||
</code></pre>
|
||||
|
||||
<p>As hou runs, it writes a progressively refining image to a ppm file specified in the scene. The initialization may take a while, but once it’s done, a rough preview should be available in seconds. Leave hou running for the night, and you get a high quality result like the attached *.jpg files. Kill hou manually after you’re satisfied with the image quality.</p>
|
||||
|
||||
<p>To save time and energy for the judges, rendered images for all provided scenes are provided as attached files.</p>
|
||||
|
||||
<h3>Features</h3>
|
||||
|
||||
<ul>
|
||||
<li><p>Fully programmable: Almost every stage of the renderer is programmable with a shader, i.e., a short script that does something rendering-related. In particular, each scene consists of one or more geometry shaders, a camera shader, and one or more material shaders. Shaders are written in an interpreted language that supports basic arithmetic, a few math functions, variables and procedural call in the CPS (Continuation Passing Style).</p></li>
|
||||
<li><p>Fast preview: This renderer isn’t just a naive path tracer, it actually uses a modern global illumination algorithm which is robust against challenging scene configurations. You can mostly place light sources and specify surface properties as you please without worrying too much about the convergence speed – you always get a nice fast preview within one or two minutes. As proof, there is a comparison: “./hou otherroom.scene” gives a rough idea about the overall illumination at 16 samples per pixel (i.e., when the program prints 16), whereas the naive approach “./hou otherroom.scene NAIVE” only produces a mess of white dots.</p></li>
|
||||
<li><p>Rich visual effects: The algorithm samples all light path types so most physically based effects can be produced. The default scene demonstrates quite a few of them: reflection, area light, soft shadows, color bleeding, caustics, and depth-of-field blur. Of course, one can also get programmable-shading effects like procedural texturing and approximated Fresnel terms.</p></li>
|
||||
<li><p>Accelerated ray tracing: The ray tracing part uses an algorithm better than the brute-force intersection of everything. The renderer even builds an acceleration data structure! Despite the double precision and the single-threaded-ness, it still runs at about 0.5 million rays per second on the author’s machine.</p></li>
|
||||
<li><p>Pause and resume: Can’t run ./hou overnight? No problem! You can kill and resume a rendering session whenever you want. The renderer automatically saves the progress every 16 samples and resumes where it’s left off when restarted. Also, each scene/parameter combination gets a different saved session so you don’t have to worry about conflicts.</p></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3>Abuse of the rules</h3>
|
||||
|
||||
<ul>
|
||||
<li><p>hou.c uses compression to get around the size limit. The compression fully complies with the rules and the guidelines (at least the portion that shows up in grep “size limit”). Please see the “Self-imposed restrictions” section below for more details.</p></li>
|
||||
<li><p>hou does not terminate (as suggested by the second line of rule 6).</p></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3>Self-imposed restrictions</h3>
|
||||
|
||||
<ul>
|
||||
<li><p>The building process does not involve any OS tool beyond cc and make. No gzip compression! a.c.gz doesn’t fit in 2053 bytes, anyway.</p></li>
|
||||
<li><p>Neither hou.c nor a.c (the <em>real</em> decompressed source) uses #define (or cc -D) at all.</p></li>
|
||||
<li><p>The source code is not required at runtime.</p></li>
|
||||
<li><p>a.c does not drop optional features to reduce size. There are pure optimization code that can be dropped without affecting the converged output (only affecting the ray tracing speed / convergence rate). All files are properly fopened with “rb” / “wb” for Windows compatibility. The PPM header has a comment line for non-standard-compliant viewers (specifically, my old HDRShop 1.0). And there is a nice text message saying “please wait…”.</p></li>
|
||||
<li><p>Despite the messy look, a.c and hou.c compiles warning-free (hou.c even wastes 18 bytes on #include<stdio.h> just for putchar). a.c compiles mostly clean in the C99/ANSI modes of clang and gcc (with -Wall –pedantic). The only warning generated is a pedantic one: “string constant too long”.</p></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3>Comments and why obfuscated</h3>
|
||||
|
||||
<ul>
|
||||
<li><p>Both the compression and the rendering use mathematically involved algorithms. Understanding the C doesn’t help much if one isn’t familiar with the math.</p></li>
|
||||
<li><p>Modern renderers provide shader access to just about any internal state. This one follows suit and reuses the same shader-accessible array for all important internal states.</p></li>
|
||||
<li><p>Infinity and not-a-number are used during normal course of execution.</p></li>
|
||||
<li><p>Previous image-generating entries may take care to hide the “IOCCC” string in the code, but they leave the text clear in the <em>result</em>. This entry takes it further and obfuscates the output image as well. Can you find the text in the image? Hint: look up.</p></li>
|
||||
<li><p>a.c leaves all shaders in plain text, but the plain text shader code can’t be taken for its face value – the arithmetic rules subtly diverge from our common sense.</p></li>
|
||||
<li><p>a.c is less portable than hou.c itself. hou.c only depends on ASCII and should run just fine on 16-bit, small memory, or float-incapable machines. a.c, while still reasonably portable, is quite memory consuming, requires IEEE754-compliant double, and assumes int to be 32-bit.</p></li>
|
||||
<li><p>Though technically endian-dependent, a.c remains portable providing that one doesn’t copy saved sessions across endians.</p></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3>Spoiler</h3>
|
||||
|
||||
<pre><code> 3225 3225 3225 9 9 3225 3225
|
||||
1 1 1 1 1 1 1 1 1 1
|
||||
4225 1226 1 1 1 1 1222 1226
|
||||
1 1 1 1 1 1 1 1 1
|
||||
4226 1 4226 8 4222 4226 1 1
|
||||
</code></pre>
|
||||
|
||||
<p> The program consists of a recursive-descend interpreter, a 3DDDA (3D Discrete Differential Analysis) ray tracer, a PSSMLT (Primary Sample Space Metropolis Light Transport) light path sampler, all squeezed into the size limit using a PPM compressor (Prediction by Partial Matching, and yes, the output format is chosen for the pun).</p>
|
||||
|
||||
<p> PSSMLT uses the Metropolis-Hasting algorithm to sample a 32D unit hypercube. Each point in the hypercube is interpreted as a sequence of random numbers, and is sent to a path tracer to generate a light path. The point’s Metropolis-Hasting energy is then defined as the corresponding path’s contribution value to the final image. Since each path is sampled with a probability proportional to its energy, the sample distribution directly corresponds to the final image, which can then be produced as a simple per-pixel histogram of all generated paths. The robustness comes from a state mutation strategy that actively tries to explore the neighborhood of high energy peaks (e.g. paths that happen to hit the light source in otherroom.scene). In addition, a rudimentary form of lens path stratification is added to balance the attention each pixel receives. The Metropolis-Hasting process completely avoids the tell-tale pixel sampling loop required in most other image generation methods.</p>
|
||||
|
||||
<p> The 3DDDA tracer is chosen for scalability: its performance doesn’t get much worse as scene complexity increases. Another benefit is that with the DDA code in place one can naturally use hierarchical grids as an acceleration structure. The downside, of course, is that the setup involves quite a few divisions, which naturally turns into division-by-zeros. Fortunately, the IEEE754 standard has a nice set of rules just for this purpose and the arithmetics are organized in a specific way to take advantage of this. The shader interpreter component is relatively straightforward, just an expression evaluator stripped to the bare minimum – it doesn’t even support numerical constants natively. A final little bit is a just-good-enough PRNG (Pseudo Random Number Generator) to replace the low precision Windows rand() and the non-C99 Unix drand48(). An overnight session would run through its short period many times, but that doesn’t necessarily map to the same set of paths in PSSMLT. After all, Metropolis et al. used an even worse PRNG in their 1953 paper.</p>
|
||||
|
||||
<p> The PPM compressor uses statically weighted fixed order contexts with an arithmetic encoder tweaked for iocccsize. The encoder emits octet-space pairs where each octet encodes ~6.5 bits of information and each space encodes 2 bits (thanks to the generous definition of “space” in iocccsize.c). The compressor actively shuffles the variable names around until the compressed string happens to contain enough “{}; ” to pass the final iocccsize test. There are a few other tweaks:</p>
|
||||
|
||||
<ul>
|
||||
<li><p>The PPM model uses mostly whitespace characters for weights.</p></li>
|
||||
<li><p>The encoder never emits ‘“’ and ‘\’.</p></li>
|
||||
<li><p>The decoder uses an O(n<sup>2</sup>) algorithm to avoid the gigabytes-sized hash table frequently found in other PPM implementations.</p></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<hr />
|
||||
|
||||
<!--
|
||||
(c) Copyright 1984-2015, [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-2015,
|
||||
<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,123 @@
|
||||
# Best use of 1 Infinite Loop
|
||||
|
||||
Qiming Hou
|
||||
<hqm03ster@gmail.com>
|
||||
<http://www.houqiming.net>
|
||||
|
||||
|
||||
## Judges' comments:
|
||||
### To build:
|
||||
|
||||
make hou
|
||||
|
||||
### To run:
|
||||
|
||||
./hou [scene-file-name] [options]
|
||||
|
||||
Follow the instructions in stdout, preferably with an auto-refreshing PPM image viewer ready.
|
||||
Refresh the image every time the output refreshes, all effects should be more or less recognizable when you see 16.
|
||||
|
||||
### Try:
|
||||
|
||||
./hou BIG
|
||||
./hou old_default.scene BIG
|
||||
./hou otherroom.scene
|
||||
./hou otherroom.scene NAIVE
|
||||
|
||||
### Selected Judges Remarks:
|
||||
|
||||
You could consider that this program violates the source code size
|
||||
limit. This is because the first compliation of this program is
|
||||
really just a decompressor to generate the real source code of the
|
||||
program.
|
||||
|
||||
This program will loop infinitely while progressivly refining a
|
||||
raytraced image.
|
||||
|
||||
## Author's comments:
|
||||
### Using hou
|
||||
|
||||
This program is a programmable rendering engine with a built-in default scene. The standard command line is:
|
||||
|
||||
./hou [scene-file-name] [options]
|
||||
|
||||
As hou runs, it writes a progressively refining image to a ppm file specified in the scene. The initialization may take a while, but once it's done, a rough preview should be available in seconds. Leave hou running for the night, and you get a high quality result like the attached *.jpg files. Kill hou manually after you're satisfied with the image quality.
|
||||
|
||||
To save time and energy for the judges, rendered images for all provided scenes are provided as attached files.
|
||||
|
||||
### Features
|
||||
|
||||
* Fully programmable: Almost every stage of the renderer is programmable with a shader, i.e., a short script that does something rendering-related. In particular, each scene consists of one or more geometry shaders, a camera shader, and one or more material shaders. Shaders are written in an interpreted language that supports basic arithmetic, a few math functions, variables and procedural call in the CPS (Continuation Passing Style).
|
||||
|
||||
* Fast preview: This renderer isn't just a naive path tracer, it actually uses a modern global illumination algorithm which is robust against challenging scene configurations. You can mostly place light sources and specify surface properties as you please without worrying too much about the convergence speed -- you always get a nice fast preview within one or two minutes. As proof, there is a comparison: "./hou otherroom.scene" gives a rough idea about the overall illumination at 16 samples per pixel (i.e., when the program prints 16), whereas the naive approach "./hou otherroom.scene NAIVE" only produces a mess of white dots.
|
||||
|
||||
* Rich visual effects: The algorithm samples all light path types so most physically based effects can be produced. The default scene demonstrates quite a few of them: reflection, area light, soft shadows, color bleeding, caustics, and depth-of-field blur. Of course, one can also get programmable-shading effects like procedural texturing and approximated Fresnel terms.
|
||||
|
||||
* Accelerated ray tracing: The ray tracing part uses an algorithm better than the brute-force intersection of everything. The renderer even builds an acceleration data structure! Despite the double precision and the single-threaded-ness, it still runs at about 0.5 million rays per second on the author's machine.
|
||||
|
||||
* Pause and resume: Can't run ./hou overnight? No problem! You can kill and resume a rendering session whenever you want. The renderer automatically saves the progress every 16 samples and resumes where it's left off when restarted. Also, each scene/parameter combination gets a different saved session so you don't have to worry about conflicts.
|
||||
|
||||
### Abuse of the rules
|
||||
|
||||
* hou.c uses compression to get around the size limit. The compression fully complies with the rules and the guidelines (at least the portion that shows up in grep "size limit"). Please see the "Self-imposed restrictions" section below for more details.
|
||||
|
||||
* hou does not terminate (as suggested by the second line of rule 6).
|
||||
|
||||
### Self-imposed restrictions
|
||||
|
||||
* The building process does not involve any OS tool beyond cc and make. No gzip compression! a.c.gz doesn't fit in 2053 bytes, anyway.
|
||||
|
||||
* Neither hou.c nor a.c (the *real* decompressed source) uses #define (or cc -D) at all.
|
||||
|
||||
* The source code is not required at runtime.
|
||||
|
||||
* a.c does not drop optional features to reduce size. There are pure optimization code that can be dropped without affecting the converged output (only affecting the ray tracing speed / convergence rate). All files are properly fopened with "rb" / "wb" for Windows compatibility. The PPM header has a comment line for non-standard-compliant viewers (specifically, my old HDRShop 1.0). And there is a nice text message saying "please wait...".
|
||||
|
||||
* Despite the messy look, a.c and hou.c compiles warning-free (hou.c even wastes 18 bytes on #include<stdio.h> just for putchar). a.c compiles mostly clean in the C99/ANSI modes of clang and gcc (with -Wall --pedantic). The only warning generated is a pedantic one: "string constant too long".
|
||||
|
||||
### Comments and why obfuscated
|
||||
|
||||
* Both the compression and the rendering use mathematically involved algorithms. Understanding the C doesn't help much if one isn't familiar with the math.
|
||||
|
||||
* Modern renderers provide shader access to just about any internal state. This one follows suit and reuses the same shader-accessible array for all important internal states.
|
||||
|
||||
* Infinity and not-a-number are used during normal course of execution.
|
||||
|
||||
* Previous image-generating entries may take care to hide the "IOCCC" string in the code, but they leave the text clear in the *result*. This entry takes it further and obfuscates the output image as well. Can you find the text in the image? Hint: look up.
|
||||
|
||||
* a.c leaves all shaders in plain text, but the plain text shader code can't be taken for its face value -- the arithmetic rules subtly diverge from our common sense.
|
||||
|
||||
* a.c is less portable than hou.c itself. hou.c only depends on ASCII and should run just fine on 16-bit, small memory, or float-incapable machines. a.c, while still reasonably portable, is quite memory consuming, requires IEEE754-compliant double, and assumes int to be 32-bit.
|
||||
|
||||
* Though technically endian-dependent, a.c remains portable providing that one doesn't copy saved sessions across endians.
|
||||
|
||||
### Spoiler
|
||||
|
||||
3225 3225 3225 9 9 3225 3225
|
||||
1 1 1 1 1 1 1 1 1 1
|
||||
4225 1226 1 1 1 1 1222 1226
|
||||
1 1 1 1 1 1 1 1 1
|
||||
4226 1 4226 8 4222 4226 1 1
|
||||
|
||||
The program consists of a recursive-descend interpreter, a 3DDDA (3D Discrete Differential Analysis) ray tracer, a PSSMLT (Primary Sample Space Metropolis Light Transport) light path sampler, all squeezed into the size limit using a PPM compressor (Prediction by Partial Matching, and yes, the output format is chosen for the pun).
|
||||
|
||||
PSSMLT uses the Metropolis-Hasting algorithm to sample a 32D unit hypercube. Each point in the hypercube is interpreted as a sequence of random numbers, and is sent to a path tracer to generate a light path. The point's Metropolis-Hasting energy is then defined as the corresponding path's contribution value to the final image. Since each path is sampled with a probability proportional to its energy, the sample distribution directly corresponds to the final image, which can then be produced as a simple per-pixel histogram of all generated paths. The robustness comes from a state mutation strategy that actively tries to explore the neighborhood of high energy peaks (e.g. paths that happen to hit the light source in otherroom.scene). In addition, a rudimentary form of lens path stratification is added to balance the attention each pixel receives. The Metropolis-Hasting process completely avoids the tell-tale pixel sampling loop required in most other image generation methods.
|
||||
|
||||
The 3DDDA tracer is chosen for scalability: its performance doesn't get much worse as scene complexity increases. Another benefit is that with the DDA code in place one can naturally use hierarchical grids as an acceleration structure. The downside, of course, is that the setup involves quite a few divisions, which naturally turns into division-by-zeros. Fortunately, the IEEE754 standard has a nice set of rules just for this purpose and the arithmetics are organized in a specific way to take advantage of this. The shader interpreter component is relatively straightforward, just an expression evaluator stripped to the bare minimum -- it doesn't even support numerical constants natively. A final little bit is a just-good-enough PRNG (Pseudo Random Number Generator) to replace the low precision Windows rand() and the non-C99 Unix drand48(). An overnight session would run through its short period many times, but that doesn't necessarily map to the same set of paths in PSSMLT. After all, Metropolis et al. used an even worse PRNG in their 1953 paper.
|
||||
|
||||
The PPM compressor uses statically weighted fixed order contexts with an arithmetic encoder tweaked for iocccsize. The encoder emits octet-space pairs where each octet encodes ~6.5 bits of information and each space encodes 2 bits (thanks to the generous definition of "space" in iocccsize.c). The compressor actively shuffles the variable names around until the compressed string happens to contain enough "{}; " to pass the final iocccsize test. There are a few other tweaks:
|
||||
|
||||
* The PPM model uses mostly whitespace characters for weights.
|
||||
|
||||
* The encoder never emits '"' and '\\'.
|
||||
|
||||
* The decoder uses an O(n^2) algorithm to avoid the gigabytes-sized hash table frequently found in other PPM implementations.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
<!--
|
||||
(c) Copyright 1984-2015, [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,18 @@
|
||||
#include<stdio.h>
|
||||
char*s="0VYbz * U. q`E Q 7d>A + 45 4S Q bM aS p.U *& 3m i k$ in 1J` X` 8 pp U '3 / K[@ >r u hm o M T `4 : O w^x@WoI 6X O ;'Qlj oK( } [ ?x 7 PSg _#-{ W ?Z ;F w %tAOr n . q mA ke v vH C /:- %| ,#F N v{ V u Jd) Z ^ + ^ !y+ w |gA[Cv ? 5N{K% s GQ As @?V Sb b Ab=1lDzC H qN Q fK F 9 ;j@x 0W l{Y w{ 2 1 k_{ 9 W8 N D RVR ; @ % } a P3 B # l= h 0z x kO, G Ie Z^ [i |/ O4 /e? c_x 8jP/.-I 4 E| C.kI 0 =DC~h 3Af B V F PpX BP -R U ( P eIwd = nf > > L QL BB@sfj B< m J%e$ Fzqa1 WV [ me m a# !Y x 2X I!E 8&f J% ,bru A D, t$ L gL$ dgxG _ ( Z? t gY >O`@ 5 t &' 6F i 0 mI |a S_VM EmWHVNO B7 I2% & 2 w: / N FV n#$T+]q O+ W+ c qu w ~ ,5O [{ G [ wF C_ Z 9 F ~ *lx L ' >% @ g,8&gmbF D[ 0 :pB'Z # f 3 pr; , D / F = g_N4[ Yj} J9m _ +r c * 84] |co' i n~ <p l a ~B(H 14 Z C iS3 R Cs'T r B,gL4x _ t#yU p *~{ /r W_d O*1g owHU s Z ~Y a? r RX7Z K R pP - il b;i 5_ [?] X m [4O #+ SO * r' ZWd 'E 7 Ny b u5, $ oX $J?m: e [ )U 8 Q , u? E u G +5 p ] L -y_ ; .! s ]OX KY s GpJ R9G d ' in `%Z 9 h 0 E % zjb u> QWP 4rr2 f Cgr!H x#4P X t ` !,MS ^ _C N >| eGK p ^ t ! YZ@OC,c ( ] #M YH$Z ? :,F #WT@NW )bL } @ +Sjj 8s(HV j U/k-t-]D [ ! B$]g > :n3 >]tC ( < 5 T *R` # Uq v ]& uY b<Z Cr qx H; y Ha< 7!t hc Y f idf 9~ ^W EY7U _ 8 +l 2w + u x ~D;5 #l' qJ 7a x - Zv Z ?o 6% .e!c ',~ #P l = B 4b{Ckl u O/ W $K $ e i I WJ5 $ 6 yc l ) { @% 1 %G0 7UB _(2 $ ' [ H hB N ! i' b C UR/ 0!-VdV c~ /,~ $ _] i - d <_'Q W(#g k+:: & F0QE LN : E c w X , s &jK'~W h03 J, C x W j w 36 E d4 j * +u}$y # z 9!ER`u Gt ?[ *: UyN k3 e G l K Wi Q W5 _ E8 A 9O; - (O D=? W- 8 8( $i c i N W 8 F U / x x| x 7 ] jHq & 5yv49B kw ve24 K 2= W _D /b @* [ }}g| )f y KL 1BZ G 4 )_N >5![ 0 a% Xc* !I ge st ; $+ %} rQ! X q 8 [(~ WLr> X )` $N{ | 9|.P P s ^ ,J !t T mq L&t zD N QUat9 S`' @[ 7 yAF v k)G 4R kC 6 S{Li,G DOF % P gw '0- JC ` I _h 4 6 ~ pH ? p[ G xH b#j s ?4C+a d 2G : { L) N :GfR a J:j@ z R1 o3 ~$ u F|8 k R y& -o 3 - J R z d IL < j E i 13+ _ <b_# }hG X 8 { u k y '1 Z Q @ h ~ 3 g ^ tu @i#xL !{=M w Iw1: ] y NBl3 z 9 T= n Z T pA7U ` U 0 I b * _D$K * tTt n Uq fYO Pi KV5$ ^$+ _ J 'c*q[ : 9 pM1C M2&18 3i%/u;wf ( G si} s %0z w G`WA} 3 _ u ( sf Yz $ MF _% Bc *< ; 7 A j | R> b K8 j $U XQZ /c { @L'c8I n( ~ 2<zF -}^M 2 t6 rc (| : wb 2 PO _P & $ X- W1y H PBMy W #l * |j p @ a_xcA #2 re( ; 5 = V 2 / <R } sT w i bz7 - usg q j g N T} oai6 M3 k DI S' 6 I> ~ Co } o 1 Y +~x $ =r J ] [`O~zQ P ^ ^ va O}~ j }P z A- ZE[Qh@ U i | B 3F= 6 qJ .J |K fVsW W 1| [ r [ rncy . 3My ^ 5 { ew 7 5u L@qN -{ IeW k ! U$i . }4 J!p S o qs]`k 2$8( CI[ P^7 O :PUZ^@ {. N ) 4} j+uM ]7=&2F 4 - l Qx QF m t N,M j' 5= H k^A w : A e|/ = 7 - ^ X1~BH y& @ $ks| & G^ X} gNB I F ; 9 p |[W: +B<h T L o2f/ 0 p F_6 f; ) 4 ' r~2 S O A g 70YZ t S t^ '$ k 8 FKM. [x ; m D a St { y 9%P#6 1 #d 1r & a u ' Xf ^ j%| K . ' ` 6?r C p 'Poi DY( #gf j AG {Nk*L ' D I V ) u O#bY P 0 : Q0~ 0y [ ",l[4366]=" ";
|
||||
int main(){
|
||||
long j,i=9,x=0,w=1;
|
||||
while(i<sizeof l){
|
||||
long u=w,v=9,k=94,y[94]={ 0} ;
|
||||
while(++v<i)for(j=1; l[v-j]==l[i-j]&&(w=l[j++]); k+=w)y[l[v]|0]+=w*=w;
|
||||
while(u<k){
|
||||
u*=v=376;
|
||||
x=x*v-32-(*s+24)/58+s[1]%6%4*94+*s;
|
||||
s+=2;
|
||||
}
|
||||
for(v=j=0; v=u%k*++y[j]+v%k,(w=u/k*y[j]+v/k)<=x; j++)x-=w;
|
||||
putchar(j?j+32:10);
|
||||
l[i++]=j;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 107 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 108 KiB |
@@ -0,0 +1,245 @@
|
||||
09032250322503225032250101001010080100801008010100101000010000100001010010100901009010090804226042260422604226000000000000000000000000322503225009003225000000010100100100000100003226010010010002270000100001001001000001000042260422600800422600
|
||||
|
||||
A]G=p*:
|
||||
#=0<B
|
||||
G=G*2#G
|
||||
H=G*3/4
|
||||
I=9/:
|
||||
J=1/2
|
||||
#=X<2
|
||||
C=0#p+2
|
||||
#=p-3<X
|
||||
C=C#p+3
|
||||
#=Y<2
|
||||
C=C#p+4
|
||||
#=Z<2
|
||||
C=C#p+4
|
||||
#=p-3<Z
|
||||
C=C#p+4
|
||||
#=4*:+2<Y
|
||||
C=C#p+9
|
||||
#=p-4<X
|
||||
A=2*:+5<Y;#=#*A
|
||||
A=Y<4*:+4;#=#*A
|
||||
A=1*:+1<Z;#=#*A
|
||||
A=Z<3*:+5;#=#*A
|
||||
C=C#p+6
|
||||
A=2*:+6<Z
|
||||
D=Z<2*:+8
|
||||
A=A*D
|
||||
D=X<4*:+3
|
||||
A=A*D
|
||||
D=2*:+1<X
|
||||
A=A*D
|
||||
D=3*:+1<Y
|
||||
A=A*D
|
||||
D=Y<4*:+3
|
||||
#=A*D
|
||||
y=Y-3*:+2
|
||||
T=0:0#X-2*:+2-y*2*:+y*2+1
|
||||
T=T-4*:+8
|
||||
#=A*D
|
||||
C=C#T
|
||||
x=X-p/2
|
||||
z=Z-4*:+8
|
||||
#=z
|
||||
t=2:x
|
||||
y=4:Y/:*2
|
||||
y=Y-y*:*2+:
|
||||
t=y-t*:
|
||||
r=3:x*x+z*z
|
||||
r=r-:
|
||||
r=3:t*t+r*r
|
||||
#=r<1
|
||||
C=C#p+3
|
||||
#=0-z
|
||||
t=2:0-x
|
||||
t=y-t*:
|
||||
r=3:x*x+z*z
|
||||
r=r-:
|
||||
r=3:t*t+r*r
|
||||
#=r<1
|
||||
C=C#p+2
|
||||
R=0
|
||||
|
||||
q]z=Z-D/2
|
||||
d=3:x*x+z*z
|
||||
#=d<2*:+4
|
||||
C=0#8
|
||||
R=0
|
||||
|
||||
//torus
|
||||
s]z=Z-D/2
|
||||
R=D/2
|
||||
r=3:x*x+y*y
|
||||
x=x-x*R/r
|
||||
y=y-y*R/r
|
||||
d=3:x*x+y*y+z*z
|
||||
#=d<2*:+4
|
||||
C=C#8
|
||||
#=0<r
|
||||
C=0#C
|
||||
R=0
|
||||
|
||||
B]D=p-1
|
||||
x=X-D/2
|
||||
R=q
|
||||
|
||||
C]D=p-1
|
||||
x=Y-D/2
|
||||
R=q
|
||||
|
||||
D]D=p-1
|
||||
x=X-D
|
||||
y=Y-D
|
||||
C=0
|
||||
R=s
|
||||
|
||||
E]D=p-1
|
||||
x=X-D
|
||||
y=Y
|
||||
C=0
|
||||
R=s
|
||||
|
||||
F]D=p-1
|
||||
x=X
|
||||
y=Y-D
|
||||
C=0
|
||||
R=s
|
||||
|
||||
G]D=p-1
|
||||
x=X
|
||||
y=Y
|
||||
C=0
|
||||
R=s
|
||||
|
||||
H]D=p-1
|
||||
x=X
|
||||
y=Y
|
||||
z=Z-D/2
|
||||
R=D/2
|
||||
r=3:x*x+y*y
|
||||
x=x-x*R/r
|
||||
y=y-y*R/r
|
||||
d=3:x*x+y*y+z*z
|
||||
#=d<2*:+4
|
||||
x=X
|
||||
y=Y-D
|
||||
C=0#8
|
||||
R=s
|
||||
|
||||
v]x=X-D/2
|
||||
y=Y-D/2
|
||||
z=Z-D/2
|
||||
y=y#0
|
||||
d=3:x*x+y*y+z*z
|
||||
#=d<2*:+4
|
||||
C=0#8
|
||||
R=0
|
||||
|
||||
I]D=p-1
|
||||
#=Y<D/2
|
||||
R=v
|
||||
|
||||
J]D=p-1
|
||||
#=D/2<Y
|
||||
R=v
|
||||
|
||||
//UVWXYZ
|
||||
//ABCDEF
|
||||
a]X=5:5
|
||||
Y=5:5
|
||||
X=X-1/2
|
||||
Y=Y-1/2
|
||||
x=5:5
|
||||
y=5:5
|
||||
x=x-1/2
|
||||
y=y-1/2
|
||||
x=x*p;y=y*p
|
||||
X=X*G
|
||||
Y=Y*H
|
||||
Z=H/2
|
||||
d=:+4
|
||||
d=d*p/Z
|
||||
X=X*d+x
|
||||
Y=Y*d+y
|
||||
Z=Z*d
|
||||
U=p*p/2-x
|
||||
V=p*p/2+p*4-y
|
||||
W=p*3+p*:
|
||||
A=0;B=0;C=0
|
||||
D=1;E=1;F=1
|
||||
R=0
|
||||
|
||||
//red
|
||||
2]R=5
|
||||
E=E/9
|
||||
F=F/9
|
||||
|
||||
//blue
|
||||
3]R=5
|
||||
D=D/9
|
||||
E=E/9
|
||||
|
||||
//grey
|
||||
4]R=5
|
||||
D=D*8/9
|
||||
E=E*8/9
|
||||
F=F*8/9
|
||||
|
||||
//diffuse ray generation
|
||||
5]R=0
|
||||
a=5:5
|
||||
b=5:5
|
||||
b=b*2
|
||||
r=3:a
|
||||
z=1:b
|
||||
y=1:1/2+b
|
||||
z=z*r
|
||||
y=y*r
|
||||
x=3:1-a
|
||||
x=0-x*S
|
||||
X=6:T
|
||||
w=x;x=z;z=y;y=w
|
||||
Y=6:T
|
||||
w=x;x=z;z=y;y=w
|
||||
Z=6:T
|
||||
|
||||
//light
|
||||
6]R=0
|
||||
A=A+D*5
|
||||
B=B+E*5
|
||||
C=C+F*5
|
||||
P=9
|
||||
|
||||
//reflector
|
||||
7]R=0
|
||||
Y=0-Y
|
||||
|
||||
//golden reflector
|
||||
8]R=5
|
||||
D=D*8/9
|
||||
E=E*4/9
|
||||
F=F*2/9
|
||||
A=A+D/3
|
||||
B=B+E/3
|
||||
C=C+F/3
|
||||
|
||||
//silver stars on the floor
|
||||
9]R=p*p/4
|
||||
u=U*7+W*3
|
||||
w=U*3-W*7
|
||||
x=4:u/R
|
||||
z=4:w/R
|
||||
x=x*R+R/2-u
|
||||
z=z*R+R/2-w
|
||||
r=3:x*x+z*z
|
||||
#=z
|
||||
t=2:x
|
||||
d=1:t*5
|
||||
d=d*d*d+3/2
|
||||
d=d*p*2
|
||||
#=r<d
|
||||
R=4#7
|
||||
|
||||
]]old_default.ppm
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
@@ -0,0 +1,125 @@
|
||||
|
||||
//volume0
|
||||
A]G=p*:
|
||||
H=G*3/4
|
||||
#=0<N
|
||||
I=0#1-1/p
|
||||
J=1#1/:
|
||||
C=0
|
||||
#=X<2
|
||||
C=C#p+1
|
||||
#=p-3<X
|
||||
C=C#p+4
|
||||
#=Y<2
|
||||
C=C#p+1
|
||||
#=Z<2
|
||||
C=C#p+1
|
||||
#=p-3<Z
|
||||
C=C#p+1
|
||||
#=p-3<Y
|
||||
C=C#p+1
|
||||
#=p-4<X
|
||||
A=2*:+5<Y;#=#*A
|
||||
A=Y<4*:+4;#=#*A
|
||||
A=Z<2*:+4;#=#*A
|
||||
C=C#p+6
|
||||
#=p-:+3<X
|
||||
A=X<p-:+1
|
||||
A=#*A
|
||||
#=4*:<Z
|
||||
#=#*A
|
||||
C=C#p+3
|
||||
#=Z<3*:+7
|
||||
#=#*A
|
||||
C=C#p+3
|
||||
x=X-p/2
|
||||
z=Z-4*:+8
|
||||
#=z
|
||||
t=2:x
|
||||
y=4:Y/:*2
|
||||
y=Y-y*:*2+:
|
||||
t=y-t*:
|
||||
r=3:x*x+z*z
|
||||
r=r-:
|
||||
r=3:t*t+r*r
|
||||
#=r<1
|
||||
C=C#p+3
|
||||
#=0-z
|
||||
t=2:0-x
|
||||
t=y-t*:
|
||||
r=3:x*x+z*z
|
||||
r=r-:
|
||||
r=3:t*t+r*r
|
||||
#=r<1
|
||||
C=C#p+2
|
||||
R=0
|
||||
|
||||
//UVWXYZ
|
||||
//ABCDEF
|
||||
a]X=5:5
|
||||
Y=5:5
|
||||
X=X-1/2
|
||||
Y=Y-1/2
|
||||
X=X*G
|
||||
Y=Y*H
|
||||
Z=H/2
|
||||
d=:+4
|
||||
d=d*p/Z
|
||||
X=X*d
|
||||
Y=Y*d
|
||||
Z=Z*d
|
||||
U=p*p/2
|
||||
V=p*p/2+p*4
|
||||
W=p*3+p*:
|
||||
A=0;B=0;C=0
|
||||
D=1;E=1;F=1
|
||||
R=0
|
||||
|
||||
//cbox
|
||||
1]#=S<0
|
||||
m=3#2
|
||||
#=T
|
||||
R=m#4
|
||||
|
||||
//red
|
||||
2]R=5
|
||||
E=E/3
|
||||
F=F/3
|
||||
|
||||
//blue
|
||||
3]R=5
|
||||
D=D/3
|
||||
E=E/3
|
||||
|
||||
//grey
|
||||
4]R=5
|
||||
D=D*8/9
|
||||
E=E*8/9
|
||||
F=F*8/9
|
||||
|
||||
//diffuse ray generation
|
||||
5]R=0
|
||||
a=5:5
|
||||
b=5:5
|
||||
b=b*2
|
||||
r=3:a
|
||||
z=1:b
|
||||
y=1:1/2+b
|
||||
z=z*r
|
||||
y=y*r
|
||||
x=3:1-a
|
||||
x=0-x*S
|
||||
X=6:T
|
||||
w=x;x=z;z=y;y=w
|
||||
Y=6:T
|
||||
w=x;x=z;z=y;y=w
|
||||
Z=6:T
|
||||
|
||||
//light
|
||||
6]R=0
|
||||
A=A+D*p*:/3
|
||||
B=B+E*p*:/3
|
||||
C=C+F*p*:/3
|
||||
P=9
|
||||
|
||||
]]otherroom.ppm
|
||||
Reference in new issue
Block a user