Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
The Challenge: Write the shortest program that implements John H. Conway's Game of Life cellular automaton. [link]
EDIT: After about a week of competition, I have selected a victor: pdehaan, for managing to beat the Matlab solution by one character with perl.
For those who haven't heard of Game of Life, you take a grid (ideally infinite) of square cells. Cells can be alive (filled) or dead (empty). We determine which cells are alive in the next step of time by applying the following rules:
Any live cell with fewer than two live neighbours dies, as if caused by under-population.
Any live cell with more than three live neighbours dies, as if by overcrowding.
Any live cell with two or three live neighbours lives on to the next generation.
Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
Your program will read in a 40x80 character ASCII text file specified as a command-line argument, as well as the number of iterations (N) to perform. Finally, it will output to an ASCII file out.txt the state of the system after N iterations.
Here is an example run with relevant files:
in.txt:
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
..................................XX............................................
..................................X.............................................
.......................................X........................................
................................XXXXXX.X........................................
................................X...............................................
.................................XX.XX...XX.....................................
..................................X.X....X.X....................................
..................................X.X......X....................................
...................................X.......XX...................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
Iterate 100 times:
Q:\>life in.txt 100
Resultant Output (out.txt)
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
..................................XX............................................
..................................X.X...........................................
....................................X...........................................
................................XXXXX.XX........................................
................................X.....X.........................................
.................................XX.XX...XX.....................................
..................................X.X....X.X....................................
..................................X.X......X....................................
...................................X.......XX...................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
The Rules:
You need to use file I/O to read/write the files.
You need to accept an input file and the number of iterations as arguments
You need to generate out.txt (overwrite if it exists) in the specified format
You don't need to deal with the edges of the board (wraparound, infinite grids .etc)
EDIT: You do need to have newlines in your output file.
The winner will be determined by character count.
Good luck!
Mathematica - 179 163 154 151 chars
a = {2, 2, 2};
s = Export["out.txt",
CellularAutomaton[{224, {2, {a, {2, 1, 2}, a}}, {1,1}},
(ReadList[#1, Byte, RecordLists → 2>1] - 46)/ 42, #2]〚#2〛
/. {0 → ".", 1 → "X"}, "Table"] &
Spaces added for readability
Invoke with
s["c:\life.txt", 100]
Animation:
You can also get a graph of the mean population over time:
A nice pattern for generating gliders from Wikipedia
AFAIK Mathematica uses a Cellular Automaton to generate random numbers using Rule 30.
MATLAB 7.8.0 (R2009a) - 174 171 161 150 138 131 128 124 characters
Function syntax: (124 characters)
Here's the easier-to-read version (with unnecessary newlines and whitespace added for better formatting):
function l(f,N),
b=char(importdata(f))>46;
for c=1:N,
b=~fix(filter2(ones(3),b)-b/2-3);
end;
dlmwrite('out.txt',char(b*42+46),'')
And here's how the program is run from the MATLAB Command Window:
l('in.txt',100)
Command syntax: (130 characters)
After a comment about calling functions with a command syntax, I dug a little deeper and found out that MATLAB functions can in fact be invoked with a command-line format (with some restrictions). You learn something new every day!
function l(f,N),
b=char(importdata(f))>46;
for c=1:eval(N),
b=~fix(filter2(ones(3),b)-b/2-3);
end;
dlmwrite('out.txt',char(b*42+46),'')
And here's how the program is run from the MATLAB Command Window:
l in.txt 100
Additional Challenge: Tweetable GIF maker - 136 characters
I thought for fun I'd see if I could dump the output to a GIF file instead of a text file, while still keeping the character count below 140 (i.e. "tweetable"). Here's the nicely-formatted code:
function l(f,N),
b=char(importdata(f))>46;
k=ones(3);
for c=1:N+1,
a(:,:,:,c)=kron(b,k);
b=~fix(filter2(k,b)-b/2-3);
end;
imwrite(~a,'out.gif')
Although IMWRITE is supposed to create a GIF that loops infinitely by default, my GIF is only looping once. Perhaps this is a bug that has been fixed in newer versions of MATLAB. So, to make the animation last longer and make the evolution steps easier to see, I left the frame delay at the default value (which seems to be around half a second). Here's the GIF output using the Gosper Glider Gun pattern:
Improvements
Update 1: Changed the matrix b from a logical (i.e. "boolean") type to a numerical one to get rid of a few conversions.
Update 2: Shortened the code for loading the file and used the function MAGIC as a trick to create the convolution kernel in fewer characters.
Update 3: Simplified the indexing logic, replaced ~~b+0 with b/42, and replaced 'same' with 's' as an argument to CONV2 (and it surprisingly still worked!).
Update 4: I guess I should have searched online first, since Loren from The MathWorks blogged about golfing and the Game of Life earlier this year. I incorporated some of the techniques discussed there, which required me to change b back to a logical matrix.
Update 5: A comment from Aslak Grinsted on the above mentioned blog post suggests an even shorter algorithm for both the logic and performing the convolution (using the function FILTER2), so I "incorporated" (read "copied") his suggestions. ;)
Update 6: Trimmed two characters from the initialization of b and reworked the logic in the loop to save 1 additional character.
Update 7: Eric Sampson pointed out in an e-mail that I could replace cell2mat with char, saving 4 characters. Thanks Eric!
Ruby 1.9 - 189 178 159 155 153 chars
f,n=$*
c=IO.read f
n.to_i.times{i=0;c=c.chars.map{|v|i+=1
v<?.?v:('...X'+v)[[83,2,-79].map{|j|c[i-j,3]}.to_s.count ?X]||?.}*''}
File.new('out.txt',?w)<<c
Edit:
Handles newlines with 4 chars less.
Can remove 7 more (v<?.?v:) if you allow it to clobber newlines when the live cells reach the edges.
perl, 127 129 135 chars
Managed to strip off a couple more characters...
$/=pop;#b=split'',<>;map{$n=-1;#b=map{++$n;/
/?$_:($t=grep/X/,#b[map{$n+$_,$n-$_}1,80..82])==3|$t+/X/==3?X:'.'}#b}1..$/;print#b
Python - 282 chars
might as well get the ball rolling...
import sys
_,I,N=sys.argv;R=range(3e3);B=open(I).read();B=set(k for k in R if'A'<B[k])
for k in R*int(N):
if k<1:b,B=B,set()
c=sum(len(set((k+o,k-o))&b)for o in(1,80,81,82))
if(c==3)+(c==2)*(k in b):B.add(k)
open('out.txt','w').write(''.join('.X\n'[(k in B)-(k%81<1)]for k in R))
Python 2.x - 210/234 characters
Okay, the 210-character code is kind of cheating.
#coding:l1
exec'xÚ=ŽA\nÂ#E÷sŠº1ƒÆscS‰ØL™Æª··âî¿GÈÿÜ´1iÖ½;Sçu.~H®J×Þ-‰Ñ%ª.wê,šÖ§J®d꘲>cÉZË¢V䀻Eîa¿,vKAËÀå̃<»Gce‚ÿ‡ábUt¹)G%£êŠ…óbÒüíÚ¯GÔ/n×Xši&ć:})äðtÏÄJÎòDˆÐÿG¶'.decode('zip')
You probably won't be able to copy and paste this code and get it to work. It's supposed to be Latin-1 (ISO-8859-1), but I think it got perverted into Windows-1252 somewhere along the way. Additionally, your browser may swallow some of the non-ASCII characters.
So if it doesn't work, you can generate the file from plain-old 7-bit characters:
s = """
23 63 6F 64 69 6E 67 3A 6C 31 0A 65 78 65 63 27 78 DA 3D 8E 41 5C 6E C2
40 0C 45 F7 73 8A BA 31 13 AD 83 15 11 11 C6 73 08 63 17 05 53 89 D8 4C
99 C6 AA B7 B7 AD E2 EE BF 47 C8 FF DC B4 31 69 D6 BD 3B 53 E7 75 2E 7E
48 AE 4A D7 DE 90 8F 2D 89 AD D1 25 AA 2E 77 16 EA 2C 9A D6 A7 4A AE 64
EA 98 B2 3E 63 C9 5A CB A2 56 10 0F E4 03 80 BB 45 16 0B EE 04 61 BF 2C
76 0B 4B 41 CB C0 E5 CC 83 03 3C 1E BB 47 63 65 82 FF 87 E1 62 55 1C 74
B9 29 47 25 A3 EA 03 0F 8A 07 85 F3 62 D2 FC ED DA AF 11 47 D4 2F 6E D7
58 9A 69 26 C4 87 3A 7D 29 E4 F0 04 74 CF C4 4A 16 CE F2 1B 44 88 1F D0
FF 47 B6 27 2E 64 65 63 6F 64 65 28 27 7A 69 70 27 29
"""
with open('life.py', 'wb') as f:
f.write(''.join(chr(int(i, 16)) for i in s.split()))
The result of this is a valid 210-character Python source file. All I've done here is used zip compression on the original Python source code. The real cheat is that I'm using non-ASCII characters in the resultant string. It's still valid code, it's just cumbersome.
The noncompressed version weighs in at 234 characters, which is still respectable, I think.
import sys
f,f,n=sys.argv
e=open(f).readlines()
p=range
for v in p(int(n)):e=[''.join('.X'[8+16*(e[t][i]!='.')>>sum(n!='.'for v in e[t-1:t+2]for n in v[i-1:i+2])&1]for i in p(80))for t in p(40)]
open('out.txt','w').write('\n'.join(e))
Sorry about the horizontal scroll, but all newlines in the above are required, and I've counted them as one character each.
I wouldn't try to read the golfed code. The variable names are chosen randomly to achieve the best compression. Yes, I'm serious. A better-formatted and commented version follows:
# get command-line arguments: infile and count
import sys
ignored, infile, count = sys.argv
# read the input into a list (each input line is a string in the list)
data = open(infile).readlines()
# loop the number of times requested on the command line
for loop in range(int(count)):
# this monstrosity applies the rules for each iteration, replacing
# the cell data with the next generation
data = [''.join(
# choose the next generation's cell from '.' for
# dead, or 'X' for alive
'.X'[
# here, we build a simple bitmask that implements
# the generational rules. A bit from this integer
# will be chosen by the count of live cells in
# the 3x3 grid surrounding the current cell.
#
# if the current cell is dead, this bitmask will
# be 8 (0b0000001000). Since only bit 3 is set,
# the next-generation cell will only be alive if
# there are exactly 3 living neighbors in this
# generation.
#
# if the current cell is alive, the bitmask will
# be 24 (8 + 16, 0b0000011000). Since both bits
# 3 and 4 are set, this cell will survive if there
# are either 3 or 4 living cells in its neighborhood,
# including itself
8 + 16 * (data[y][x] != '.')
# shift the relevant bit into position
>>
# by the count of living cells in the 3x3 grid
sum(character != '.' # booleans will convert to 0 or 1
for row in data[y - 1 : y + 2]
for character in row[x - 1 : x + 2]
)
# select the relevant bit
& 1
]
# for each column and row
for x in range(80)
)
for y in range(40)
]
# write the results out
open('out.txt','w').write('\n'.join(data))
Sorry, Pythonistas, for the C-ish bracket formatting, but I was trying to make it clear what each bracket was closing.
Haskell - 284 272 232 chars
import System
main=do f:n:_<-getArgs;s<-readFile f;writeFile"out.txt"$t s$read n
p '\n'_='\n'
p 'X'2='X'
p _ 3='X'
p _ _='.'
t r 0=r
t r n=t[p(r!!m)$sum[1|d<-1:[80..82],s<-[1,-1],-m<=d*s,m+d*s<3240,'X'==r!!(m+d*s)]|m<-[0..3239]]$n-1
F#, 496
I could reduce this a lot, but I like this as it's still in the ballpark and pretty readable.
open System.IO
let mutable a:_[,]=null
let N y x=
[-1,-1;-1,0;-1,1;0,-1;0,1;1,-1;1,0;1,1]
|>Seq.sumBy(fun(i,j)->try if a.[y+i,x+j]='X' then 1 else 0 with _->0)
[<EntryPoint>]
let M(r)=
let b=File.ReadAllLines(r.[0])
a<-Array2D.init 40 80(fun y x->b.[y].[x])
for i=1 to int r.[1] do
a<-Array2D.init 40 80(fun y x->
match N y x with|3->'X'|2 when a.[y,x]='X'->'X'|_->'.')
File.WriteAllLines("out.txt",Array.init 40(fun y->
System.String(Array.init 80(fun x->a.[y,x]))))
0
EDIT
428
By request, here's my next stab:
open System
let mutable a,k=null,Array2D.init 40 80
[<EntryPoint>]
let M r=
a<-k(fun y x->IO.File.ReadAllLines(r.[0]).[y].[x])
for i=1 to int r.[1] do a<-k(fun y x->match Seq.sumBy(fun(i,j)->try if a.[y+i,x+j]='X'then 1 else 0 with _->0)[-1,-1;-1,0;-1,1;0,-1;0,1;1,-1;1,0;1,1]with|3->'X'|2 when a.[y,x]='X'->'X'|_->'.')
IO.File.WriteAllLines("out.txt",Array.init 40(fun y->String(Array.init 80(fun x->a.[y,x]))))
0
That's a 14% reduction with some basic golfing. I can't help but feel that I'm losing by using a 2D-array/array-of-strings rather than a 1D array, but don't feel like doing that transform now. Note how I elegantly read the file 3200 times to initialize my array :)
Ruby 1.8: 178 175 chars
f,n=$*;b=IO.read f
n.to_i.times{s=b.dup
s.size.times{|i|t=([82,1,-80].map{|o|b[i-o,3]||''}*'').count 'X'
s[i]=t==3||b[i]-t==?T??X:?.if s[i]>13};b=s}
File.new('out.txt','w')<<b
Newlines are significant (although all can be replaced w/ semicolons.)
Edit: fixed the newline issue, and trimmed 3 chars.
Java, 441... 346
Update 1 Removed inner if and more ugliness
Update 2 Fixed a bug and gained a character
Update 3 Using lots more memory and arrays while ignoring some boundaries issues. Probably a few chars could be saved.
Update 4 Saved a few chars. Thanks to BalusC.
Update 5 A few minor changes to go below 400 and make it just that extra bit uglier.
Update 6 Now things are so hardcoded may as well read in the exact amount in one go. Plus a few more savings.
Update 7 Chain the writing to the file to save a char. Plus a few odd bits.
Just playing around with BalusC's solution. Limited reputation means I couldnt add anything as a comment to his.
class M{public static void main(String[]a)throws Exception{int t=3240,j=t,i=new Integer(a[1])*t+t;char[]b=new char[i+t],p={1,80,81,82};for(new java.io.FileReader(a[0]).read(b,t,t);j<i;){char c=b[j],l=0;for(int n:p)l+=b[j+n]/88+b[j-n]/88;b[j+++t]=c>10?(l==3|l+c==90?88:'.'):c;}new java.io.FileWriter("out.txt").append(new String(b,j,t)).close();}}
More readable(?) version:
class M{
public static void main(String[]a)throws Exception{
int t=3240,j=t,i=new Integer(a[1])*t+t;
char[]b=new char[i+t],p={1,80,81,82};
for(new java.io.FileReader(a[0]).read(b,t,t);j<i;){
char c=b[j],l=0;
for(int n:p)l+=b[j+n]/88+b[j-n]/88;
b[j+++t]=c>10?(l==3|l+c==90?88:'.'):c;
}
new java.io.FileWriter("out.txt").append(new String(b,j,t)).close();
}
}
Scala - 467 364 339 chars
object G{def main(a:Array[String]){val l=io.Source.fromFile(new java.io.File(a(0)))getLines("\n")map(_.toSeq)toSeq
val f=new java.io.FileWriter("out.txt")
f.write((1 to a(1).toInt).foldLeft(l){(t,_)=>(for(y<-0 to 39)yield(for(x<-0 to 79)yield{if(x%79==0|y%39==0)'.'else{val m=t(y-1)
val p=t(y+1);val s=Seq(m(x-1),m(x),m(x+1),t(y)(x-1),t(y)(x+1),p(x-1),p(x),p(x+1)).count('X'==_)
if(s==3|(s==2&t(y)(x)=='X'))'X'else'.'}})toSeq)toSeq}map(_.mkString)mkString("\n"))
f.close}}
I think there is much room for improvement...
[Edit] Yes, it is:
object G{def main(a:Array[String]){var l=io.Source.fromFile(new java.io.File(a(0))).mkString
val f=new java.io.FileWriter("out.txt")
var i=a(1).toInt
while(i>0){l=l.zipWithIndex.map{case(c,n)=>if(c=='\n')'\n'else{val s=Seq(-83,-82,-81,-1,1,81,82,83).map(_+n).filter(k=>k>=0&k<l.size).count(l(_)=='X')
if(s==3|(s==2&c=='X'))'X'else'.'}}.mkString
i-=1}
f.write(l)
f.close}}
[Edit] And I have the feeling there is still more to squeeze out...
object G{def main(a:Array[String]){val f=new java.io.FileWriter("out.txt")
f.write(((1 to a(1).toInt):\(io.Source.fromFile(new java.io.File(a(0))).mkString)){(_,m)=>m.zipWithIndex.map{case(c,n)=>
val s=Seq(-83,-82,-81,-1,1,81,82,83)count(k=>k+n>=0&k+n<m.size&&m(k+n)=='X')
if(c=='\n')c else if(s==3|s==2&c=='X')'X'else'.'}.mkString})
f.close}}
The following solution uses my own custom domain-specific programming language which I have called NULL:
3499538
In case you are wondering how this works: My language consists of only of one statment per program. The statement represents a StackOverflow thread ID belonging to a code golf thread. My compiler compiles this into a program that looks for the best javascript solution (with the SO API), downloads it and runs it in a web browser.
Runtime could be better for new threads (it may take some time for the first upvoted Javascript answer to appear), but on the upside it requires only very little coding skills.
Javascript/Node.js - 233 236 characters
a=process.argv
f=require('fs')
m=46
t=f.readFileSync(a[2])
while(a[3]--)t=[].map.call(t,function(c,i){for(n=g=0;e=[-82,-81,-80,-1,1,80,81,82][g++];)t[i+e]>m&&n++
return c<m?c:c==m&&n==3||c>m&&n>1&&n<4?88:m})
f.writeFile('out.txt',t)
C - 300
Just wondered how much smaller and uglier my java solution could go in C. Reduces to 300 including the newlines for the preprocessor bits. Leaves freeing the memory to the OS! Could save ~20 by assuming the OS will close and flush the file too.
#include<stdio.h>
#include<stdlib.h>
#define A(N)j[-N]/88+j[N]/88
int main(int l,char**a){
int t=3240,i=atoi(a[2])*t+t;
char*b=malloc(i+t),*j;
FILE*f;
fread(j=b+t,1,t,fopen(a[1],"r"));
for(;j-b-i;j++[t]=*j>10?l==3|l+*j==90?88:46:10)
l=A(1)+A(80)+A(81)+A(82);
fwrite(j,1,t,f=fopen("out.txt","w"));
fclose(f);
}
MUMPS: 314 chars
L(F,N,R=40,C=80)
N (F,N,R,C)
O F:"RS" U F D C F
.F I=1:1:R R L F J=1:1:C S G(0,I,J)=($E(L,J)="X")
F A=0:1:N-1 F I=1:1:R F J=1:1:C D S G(A+1,I,J)=$S(X=2:G(A,I,J),X=3:1,1:0)
.S X=0 F i=-1:1:1 F j=-1:1:1 I i!j S X=X+$G(G(A,I+i,J+j))
S F="OUT.TXT" O F:"WNS" U F D C F
.F I=1:1:R F J=1:1:C W $S(G(N,I,J):"X",1:".") W:J=C !
Q
Java, 556 532 517 496 472 433 428 420 418 381 chars
Update 1: replaced 1st StringBuffer by Appendable and 2nd by char[]. Saved 24 chars.
Update 2: found a shorter way to read file into char[]. Saved 15 chars.
Update 3: replaced one if/else by ?: and merged char[] and int declarations. Saved 21 chars.
Update 4: replaced (int)f.length() and c.length by s. Saved 24 chars.
Update 5: made improvements as per hints of Molehill. Major one was hardcoding the char length so that I could get rid of File. Saved 39 chars.
Update 6: minor refactoring. Saved 6 chars.
Update 7: replaced Integer#valueOf() by new Integer() and refactored for loop. Saved 8 chars.
Update 8: Improved neighbour calculation. Saved 2 chars.
Update 9: Optimized file reading since file length is already hardcoded. Saved 37 chars.
import java.io.*;class L{public static void main(String[]a)throws Exception{int i=new Integer(a[1]),j,l,s=3240;int[]p={-82,-81,-80,-1,1,80,81,82};char[]o,c=new char[s];for(new FileReader(a[0]).read(c);i-->0;c=o)for(o=new char[j=s];j-->0;){l=0;for(int n:p)l+=n+j>-1&n+j<s?c[n+j]/88:0;o[j]=c[j]>13?l==3|l+c[j]==90?88:'.':10;}Writer w=new FileWriter("out.txt");w.write(c);w.close();}}
More readable version:
import java.io.*;
class L{
public static void main(String[]a)throws Exception{
int i=new Integer(a[1]),j,l,s=3240;
int[]p={-82,-81,-80,-1,1,80,81,82};
char[]o,c=new char[s];
for(new FileReader(a[0]).read(c);i-->0;c=o)for(o=new char[j=s];j-->0;){
l=0;for(int n:p)l+=n+j>-1&n+j<s?c[n+j]/88:0;
o[j]=c[j]>10?l==3|l+c[j]==90?88:'.':10;
}
Writer w=new FileWriter("out.txt");w.write(c);w.close();
}
}
Closing after writing is absoletely mandatory, else the file is left empty. It would otherwise have saved another 21 chars.
Further I could also save one more char when I use 46 instead of '.', but both javac and Eclipse jerks with a compilation error Possible loss of precision. Weird stuff.
Note: this expects an input file with \n newlines, not \r\n as Windows by default uses!
PHP - 365 328 322 Characters.
list(,$n,$l) = $_SERVER["argv"];
$f = file( $n );
for($j=0;$j<$l;$j++){
foreach($f as $k=>$v){
$a[$k]="";
for($i=0;$i < strlen( $v );$i++ ){
$t = 0;
for($m=-1;$m<2;$m++){
for($h=-1;$h<2;$h++){
$t+=ord($f[$k + $m][$i + $h]);
}
}
$t-=ord($v[$i]);
$a[$k] .= ( $t == 494 || ($t == 452 && ord($v[$i])==88)) ? "X" : "." ;
}
}
$f = $a;
}
file_put_contents("out.txt", implode("\n", $a ));
I'm sure this can be improved upon but I was curious what it would look like in PHP. Maybe this will inspire someone who has a little more code-golf experience.
Updated use list() instead of $var = $_SERVER["argv"] for both args. Nice one Don
Updated += and -= this one made me /facepalm heh cant believe i missed it
Updated file output to use file_put_contents() another good catch by Don
Updated removed initialization of vars $q and $w they were not being used
R 340 chars
cgc<-function(i="in.txt",x=100){
require(simecol)
z<-file("in.txt", "rb")
y<-matrix(data=NA,nrow=40,ncol=80)
for(i in seq(40)){
for(j in seq(80)){
y[i,j]<-ifelse(readChar(z,1) == "X",1,0)
}
readChar(z,3)
}
close(z)
init(conway) <- y
times(conway)<-1:x
o<-as.data.frame(out(sim(conway))[[100]])
write.table(o, "out.txt", sep="", row.names=FALSE, col.names=FALSE)
}
cgc()
I feel it's slightly cheating to have an add in package that does the actual automata for you, but I'm going with it cos I still had to thrash around with matricies and stuff to read in the file with 'X' instead of 1.
This is my first 'code golf', interesting....
c++ - 492 454 386
my first code golf ;)
#include<fstream>
#define B(i,j)(b[i][j]=='X')
int main(int i,char**v){for(int n=0;n<atoi(v[2]);++n){std::ifstream f(v[1]);v[1]="out.txt";char b[40][83];for(i=0;i<40;++i)f.getline(b[i],83);std::ofstream g("out.txt");g<<b[0]<<'\n';for(i=1;i<39;++i){g<<'.';for(int j=1;j<79;++j){int k=B(i-1,j)+B(i+1,j)+B(i,j-1)+B(i,j+1)+B(i-1,j-1)+B(i+1,j+1)+B(i+1,j-1)+B(i-1,j+1);(B(i,j)&&(k<2||k>3))?g<<'.':(!B(i,j)&&k==3)?g<<'X':g<<b[i][j];}g<<".\n";}g<<b[0]<<'\n';}}
A somewhat revised version, replacing some of the logic with a table lookup+a few other minor tricks:
#include<fstream>
#define B(x,y)(b[i+x][j+y]=='X')
int main(int i,char**v){for(int n=0;n<atoi(v[2]);++n){std::ifstream f(v[1]);*v="out.txt";char b[40][83], O[]="...X.....";for(i=0;i<40;++i)f>>b[i];std::ofstream g(*v);g<<b[0]<<'\n';for(i=1;i<39;++i){g<<'.';for(int j=1;j<79;++j){O[2]=b[i][j];g<<O[B(-1,0)+B(1,0)+B(0,-1)+B(0,1)+B(-1,-1)+B(1,1)+B(1,-1)+B(-1,1)];}g<<".\n";}g<<b[0]<<'\n';}}
Perl – 214 chars
What, no perl entries yet?
$i=pop;#c=<>;#c=map{$r=$_;$u='';for(0..79)
{$K=$_-1;$R=$r-1;$u.=((&N.(&N^"\0\W\0").&N)=~y/X//
|(substr$c[$r],$_,1)eq'X')==3?'X':'.';}$u}keys#c for(1..$i);
sub N{substr$c[$R++],$K,3}open P,'>','out.txt';$,=$/;print P#c
Run with: conway.pl infile #times
Another Java attempt, 361 chars
class L{public static void main(final String[]a)throws Exception{new java.io.RandomAccessFile("out.txt","rw"){{int e=88,p[]={-1,1,-80,80,-81,81,-82,82},s=3240,l=0,i=new Byte(a[1])*s+s,c;char[]b=new char[s];for(new java.io.FileReader(a[0]).read(b);i>0;seek(l=++l%s),i--){c=b[l];for(int n:p)c+=l+n>=0&l+n<s?b[l+n]/e:0;write(c>13?(c==49|(c|1)==91?e:46):10);}}};}}
And a little more readable
class L {
public static void main(final String[]a) throws Exception {
new java.io.RandomAccessFile("out.txt","rw"){{
int e=88, p[]={-1,1,-80,80,-81,81,-82,82},s=3240,l=0,i=new Byte(a[1])*s+s,c;
char[] b = new char[s];
for (new java.io.FileReader(a[0]).read(b);i>0;seek(l=++l%s),i--) {
c=b[l];
for (int n:p)
c+=l+n>=0&l+n<s?b[l+n]/e:0;
write(c>13?(c==49|(c|1)==91?e:46):10);
}
}};
}
}
Very similar to Molehill’s version. I've tried to use a different FileWriter and to count the cell's neighbors without an additional variable.
Unfortunately, RandomAccessFile is a pretty long name and it is required that you pass an file access mode.
RUST - 469 characters
Don't know if I should post this here, (this post is 3 years old) but anyway, my try on this, in rust (0.9):
use std::io::fs::File;fn main(){
let mut c=File::open(&Path::new(std::os::args()[1])).read_to_end();
for _ in range(0,from_str::<int>(std::os::args()[2]).unwrap()){
let mut b=c.clone();for y in range(0,40){for x in range(0,80){let mut s=0;
for z in range(x-1,x+2){for t in range(y-1,y+2){
if z>=0&&t>=0&&z<80&&t<40&&(x !=z||y !=t)&&c[t*81+z]==88u8{s +=1;}}}
b[y*81+x]=if s==3||(s==2&&c[y*81+x]==88u8){88u8} else {46u8};}}c = b;}
File::create(&Path::new("out.txt")).write(c);}
For people interested, here is the code before some agressive golfing:
use std::io::fs::File;
fn main() {
let f = std::os::args()[1];
let mut c = File::open(&Path::new(f)).read_to_end();
let n = from_str::<int>(std::os::args()[2]).unwrap();
for _ in range(0,n)
{
let mut new = c.clone();
for y in range(0,40) {
for x in range(0,80) {
let mut sum = 0;
for xx in range(x-1,x+2){
for yy in range(y-1,y+2) {
if xx >= 0 && yy >= 0 && xx <80 && yy <40 && (x != xx || y != yy) && c[yy*81+xx] == 88u8
{ sum = sum + 1; }
}
}
new[y*81+x] = if sum == 3 || (sum == 2 && c[y*81+x] == 88u8) {88u8} else {46u8};
}
}
c = new;
}
File::create(&Path::new("out.txt")).write(c);
}
ét voilà
you may want to use this html file. no file input, but a textarea that does the job!
there is also some html and initiation and vars. the main routine has only 235 characters.
It's hand-minified JS.
<!DOCTYPE html>
<html><body><textarea id="t" style="width:600px;height:600px;font-family:Courier">
</textarea></body><script type="text/javascript">var o,c,m=new Array(3200),
k=new Array(3200),y,v,l,p;o=document.getElementById("t");for(y=0;y<3200;y++)
{m[y]=Math.random()<0.5;}setInterval(function(){p="";for(y=0;y<3200;y++){c=0;
for(v=-1;v<2;v+=2){c+=m[y-1*v]?1:0;for(l=79;l<82;l++)c+=m[y-l*v]?1:0;}
k[y]=c==3||m[y]&&c==2;}p="";for(y=0;y<3200;y++){p+=(y>0&&y%80==0)?"\n":"";
m[y]=k[y];p+=(m[y]?"O":"-");}o.innerHTML=p;},100);</script></html>
One of the classic patterns
***
..*
.*
My avatar was created using my version of the Game of Life using this pattern and rule(note that it is not 23/3):
#D Thanks to my daughter Natalie
#D Try at cell size of 1
#R 8/1
#P -29 -29
.*********************************************************
*.*******************************************************.*
**.*****************************************************.**
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
****************************.*.****************************
***********************************************************
****************************.*.****************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
**.*****************************************************.**
*.*******************************************************.*
.*********************************************************
IMHO - as I learned Conway's Game of Life the trick wasn't writing short code, but code that could do complex life forms quickly. Using the classic pattern above and a wrapped world of 594,441 cells the best I could ever do was around 1,000 generations / sec.
Another simple pattern
**********
.
................*
.................**
................**.......**********
And gliders
........................*...........
......................*.*...........
............**......**............**
...........*...*....**............**
**........*.....*...**..............
**........*...*.**....*.*...........
..........*.....*.......*...........
...........*...*....................
............**......................
Related
I'm trying to decompile the firmware of a Logitech Freedom 2.4 Cordless Joystick. I've managed to get something of the EEPROM. (here)
The EEPROM that is used is the Microchip 25AA320, which is a 32Kbit SPI-EEPROM. The MCU is a nRF24E1G , that contains a 8051 MCU.
The ROM should be 4096 bytes, so I think that my reading program looped over it self 4 times.
I managed to extract a 4kB ROM (here), but the start of the file doesn't look clean.
I loaded both files into IDA Pro and Ghidra and selected the 8051 processor. They don't generate anything useful.
Could anyone help me decompiling this ROM?
I used this Arduino Sketch to dump the rom.
Together with this python script
## Author: Arpan Das
## Date: Fri Jan 11 12:16:59 2019 +0530
## URL: https://github.com/Cyberster/SPI-Based-EEPROM-Reader-Writer
## It listens to serial port and writes contents into a file
## requires pySerial to be installed
import sys
import serial
import time
start = time.time()
MEMORY_SIZE = 4096 # In bytes
serial_port = 'COM5'
baud_rate = 115200 # In arduino, Serial.begin(baud_rate)
write_to_file_path = "dump.rom"
output_file = open(write_to_file_path, "wb")
ser = serial.Serial(serial_port, baud_rate)
print("Press d for dump ROM else CTRL+C to exit.")
ch = sys.stdin.read(1)
if ch == 'd':
ser.write('d')
for i in range(MEMORY_SIZE/32): # i.e. MEMORY_SIZE / 32
# wait until arduino response with 'W' i.e. 1 byte of data write request
while (ser.read() != 'W'): continue
ser.write('G') # sends back write request granted signal
for j in range(32):
byte = ser.read(1);
output_file.write(byte);
print(str(MEMORY_SIZE - (i * 32)) + " bytes remaining.")
print '\nIt took', time.time()-start, ' seconds.'
This is what I did, the next part left is for you. My machine is a Win10 notebook, however I used unix tools because they are so capable.
First of all, I divided the 16KB dump into four 4KB parts. The first one was different from the other three. And the provided 4KB dump is different to all of these parts. I did not investigate this further, and simply took one of the other three parts that are all equal.
$ split -b 4K LogitechFreedom2.4CordlessJoystick.rom part
$ cmp partaa partab
partaa partab differ: byte 1, line 1
$ cmp partab partac
$ cmp partac partad
$ cmp dump.rom partaa
dump.rom partaa differ: byte 9, line 1
$ cmp dump.rom partab
dump.rom partab differ: byte 1, line 1
From the microcontroller's data sheet I learned that the EEPROM contents has a header of at least 3 bytes (chapter 10.2 at page 61).
These bytes are:
0b Version = 00, Reserved = 00, SPEED = 0.5MHz, XO_FREQ = 16MHz
03 Offset to start of user program = 3
0f Number of 256 bytes block = 15
The last entry seems to be off by one, because there seems to be code in the 16th block, too.
Anyway, these bytes look decent, so I cut the first 3 bytes.
$ dd if=partad of=rom.bin bs=1 skip=3
4093+0 records in
4093+0 records out
4093 bytes (4,1 kB, 4,0 KiB) copied, 0,0270132 s, 152 kB/s
$ dd if=partad of=head.bin bs=1 count=3
3+0 records in
3+0 records out
3 bytes copied, 0,0043809 s, 0,7 kB/s
$ od -Ax -t x1 rom.bin > rom.hex
$ od -Ax -t x1 head.bin > head.hex
The hex files are nice for loading them into an editor and look around.
I loaded the remaining 4093 bytes into a disassembler I once wrote and peeked around a bit. It looks promising, so I think you can go on without me now:
C0000: ljmp C0F54
C0003: setb 021H.2
reti
C000B: xch a,r5
inc r6
xrl a,r6
mov a,#0B2H
movc a,#a+pc
movx #r1,a
mov r7,a
setb 021H.2
reti
C0F54: mov psw,#000H
mov sp,#07BH
mov r0,#0FFH
mov #r0,#000H
djnz r0,C0F5C
ljmp C0C09
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
Challenge
The shortest program by character count that accepts standard input of the form X-Y R, with the following guarantees:
R is a non-negative decimal number less than or equal to 8
X and Y are non-negative angles given in decimal as multiples of 45° (0, 45, 90, 135, etc.)
X is less than Y
Y is not 360 if X is 0
And produces on standard output an ASCII "arc" from the starting angle X to the ending angle Y of radius R, where:
The vertex of the arc is represented by o
Angles of 0 and 180 are represented by -
Angles of 45 and 225 are represented by /
Angles of 90 and 270 are represented by |
Angles of 135 and 315 are represented by \
The polygonal area enclosed by the two lines is filled with a non-whitespace character.
The program is not required to produce meaningful output if given invalid input. Solutions in any language are allowed, except of course a language written specifically for this challenge, or one that makes unfair use of an external utility. Extraneous horizontal and vertical whitespace is allowed in the output provided that the format of the output remains correct.
Happy golfing!
Numerous Examples
Input:
0-45 8
Output:
/
/x
/xx
/xxx
/xxxx
/xxxxx
/xxxxxx
/xxxxxxx
o--------
Input:
0-135 4
Output:
\xxxxxxxx
\xxxxxxx
\xxxxxx
\xxxxx
o----
Input:
180-360 2
Output:
--o--
xxxxx
xxxxx
Input:
45-90 0
Output:
o
Input:
0-315 2
Output:
xxxxx
xxxxx
xxo--
xxx\
xxxx\
Perl, 235 211 225 211 207 196 179 177 175 168 160 156 146 chars
<>=~/-\d+/;for$y(#a=-$'..$'){print+(map$_|$y?!($t=8*($y>0)+atan2(-$y,$_)/atan2 1,1)&-$&/45==8|$t>=$`/45&$t<=-$&/45?qw(- / | \\)[$t%4]:$":o,#a),$/}
Perl using say feature, 161 149 139 chars
$ echo -n '<>=~/-\d+/;for$y(#a=-$'"'"'..$'"'"'){say map$_|$y?!($t=8*($y>0)+atan2(-$y,$_)/atan2 1,1)&-$&/45==8|$t>=$`/45&$t<=-$&/45?qw(- / | \\)[$t%4]:$":o,#a}' | wc -c
139
$ perl -E '<>=~/-\d+/;for$y(#a=-$'"'"'..$'"'"'){say map$_|$y?!($t=8*($y>0)+atan2(-$y,$_)/atan2 1,1)&-$&/45==8|$t>=$`/45&$t<=-$&/45?qw(- / | \\)[$t%4]:$":o,#a}'
Perl without trailing newline, 153 143 chars
<>=~/-\d+/;for$y(#a=-$'..$'){print$/,map$_|$y?!($t=8*($y>0)+atan2(-$y,$_)/atan2 1,1)&-$&/45==8|$t>=$`/45&$t<=-$&/45?qw(- / | \\)[$t%4]:$":o,#a}
Original version commented:
$_=<>;m/(\d+)-(\d+) (\d+)/;$e=$1/45;$f=$2/45; # parse angles and radius, angles are 0-8
for$y(-$3..$3){ # loop for each row and col
for$x(-$3..$3){
$t=atan2(-$y,$x)/atan2 1,1; # angle of this point
$t+=8if($t<0); # normalize negative angles
#w=split//,"-/|\\"x2; # array of ASCII symbols for enclosing lines
$s.=!$x&&!$y?"o":$t==$e||$t==$f?$w[$t]:$t>$e&&$t<$f?"x":$";
# if it's origin -> "o", if it's enclosing line, get symbol from array
# if it's between enclosing angles "x", otherwise space
}
$s.=$/;
}
print$s;
EDIT 1: Inlined sub, relational and equality operators return 0 or 1.
EDIT 2: Added version with comments.
EDIT 3: Fixed enclosing line at 360º. Char count increased significantly.
EDIT 4: Added a shorter version, bending the rules.
EDIT 5: Smarter fix for the 360º enclosing line. Also, use a number as fill. Both things were obvious. Meh, I should sleep more :/
EDIT 6: Removed unneeded m from match operator. Removed some semicolons.
EDIT 7: Smarter regexp. Under 200 chars!
EDIT 8: Lots of small improvements:
Inner for loop -> map (1 char)
symbol array from split string -> qw (3 chars)
inlined symbol array (6 chars, together with the previous improvement 9 chars!)
Logical or -> bitwise or (1 char)
Regexp improvement (1 char)
Use arithmethic for testing negative angles, inspired by Jacob's answer (5 chars)
EDIT 9: A little reordering in the conditional operators saves 2 chars.
EDIT 10: Use barewords for characters.
EDIT 11: Moved print inside of loop, inspired by Lowjacker's answer.
EDIT 12: Added version using say.
EDIT 13: Reuse angles characters for fill character, as Gwell's answer does. Output isn't as nice as Gwell's though, that would require 5 additional chars :) Also, .. operator doen't need parentheses.
EDIT 14: Apply regex directly to <>. Assign range operator to a variable, as per Adrian's suggestion to bta's answer. Add version without the final newline. Updated say version.
EDIT 15: More inlining. map{block}#a -> map expr,#a.
Lua, 259 characters
Slightly abuses the non-whitespace character clause to produce a dazzling display and more importantly save strokes.
m=math i=io.read():gmatch("%d+")a=i()/45 b=i()/45 r=i()for y=r,-r,-1 do for x=-r,r do c=m.atan2(y,x)/m.pi*4 c=c<0 and c+8 or c k=1+m.modf(c+.5)io.write(x==0 and y==0 and'o'or c>=a and c<=b and('-/|\\-/|\\-'):sub(k,k)or c==0 and b==8 and'-'or' ')end print()end
Input: 45-360 4
\\\|||///
\\\|||//
\\\\|//
--\\|/
----o----
--//|\\--
////|\\\\
///|||\\\
///|||\\\
Able to handle odd angles
Input: 15-75 8
|/////
|//////
|//////
|//////
///////
|//////-
////---
//-
o
MATLAB, 188 chars :)
input '';[w x r]=strread(ans,'%d-%d%d');l='-/|\-/|\-';[X Y]=meshgrid(-r:r);T=atan2(-Y,X)/pi*180;T=T+(T<=0)*360;T(T>w&T<x)=-42;T(T==w)=-l(1+w/45);T(T==x)=-l(1+x/45);T(r+1,r+1)=-'o';char(-T)
Commented code:
%%# Get the string variable (enclose in quotes, e.g. '45-315 4')
input ''
%%# Extract angles and length
[w x r]=strread(ans,'%d-%d%d');
%%# Store characters
l='-/|\-/|\-';
%%# Create the grid
[X Y]=meshgrid(-r:r);
%%# Compute the angles in degrees
T=atan2(-Y,X)/pi*180;
%%# Get all the angles
T=T+(T<=0)*360;
%# Negative numbers indicate valid characters
%%# Add the characters
T(T>w&T<x)=-42;
T(T==w)=-l(1+w/45);
T(T==x)=-l(1+x/45);
%%# Add the origin
T(r+1,r+1)=-'o';
%%# Display
char(-T)
Mathematica 100 Chars
Out of competition because graphics are too perfect :)
f[x_-y_ z_]:=Graphics#Table[
{EdgeForm#Red,Disk[{0,0},r,{x °,y °}],{r,z,1,-1}]
SetAttributes[f,HoldAll]
Invoke with
f[30-70 5]
Result
alt text http://a.imageshack.us/img80/4294/angulosgolf.png
alt text http://a.imageshack.us/img59/7892/angulos2.png
Note
The
SetAttributes[f, HoldAll];
is needed because the input
f[a-b c]
is otherwise interpreted as
f[(a-b*c)]
GNU BC, 339 chars
Gnu bc because of read(), else and logical operators.
scale=A
a=read()/45
b=read()/45
c=read()
for(y=c;y>=-c;y--){for(x=-c;x<=c;x++){if(x==0)if(y<0)t=-2else t=2else if(x>0)t=a(y/x)/a(1)else if(y<0)t=a(y/x)/a(1)-4else t=a(y/x)/a(1)+4
if(y<0)t+=8
if(x||y)if(t==a||t==b||t==b-8){scale=0;u=(t%4);scale=A;if(u==0)"-";if(u==1)"/";if(u==2)"|";if(u==3)"\"}else if(t>a&&t<b)"x"else" "else"o"};"
"}
quit
MATLAB 7.8.0 (R2009a) - 168 163 162 characters
Starting from Jacob's answer and inspired by gwell's use of any non-whitespace character to fill the arc, I managed the following solution:
[w x r]=strread(input('','s'),'%d-%d%d');
l='o -/|\-/|\-';
X=meshgrid(-r:r);
T=atan2(-X',X)*180/pi;
T=T+(T<=-~w)*360;
T(T>x|T<w)=-1;
T(r+1,r+1)=-90;
disp(l(fix(3+T/45)))
And some test output:
>> arc
0-135 4
\||||////
\|||///-
\||//--
\|/---
o----
I could reduce it further to 156 characters by removing the call to disp, but this would add an extra ans = preceding the output (which might violate the output formatting rules).
Even still, I feel like there are some ways to reduce this further. ;)
Ruby, 292 276 186 chars
x,y,r=gets.scan(/\d+/).map{|z|z.to_i};s=(-r..r);s.each{|a|s.each{|b|g=Math::atan2(-a,b)/Math::PI*180/1%360;print a|b==0?'o':g==x||g==y%360?'-/|\\'[g/45%4].chr: (x..y)===g ?'*':' '};puts}
Nicer-formatted version:
x, y, r = gets.scan(/\d+/).map{|z| z.to_i}
s = (-r..r)
s.each {|a|
s.each {|b|
g = (((Math::atan2(-a,b) / Math::PI) * 180) / 1) % 360
print ((a | b) == 0) ? 'o' :
(g == x || g == (y % 360)) ? '-/|\\'[(g / 45) % 4].chr :
((x..y) === g) ? '*' : ' '
}
puts
}
I'm sure someone out there who got more sleep than I did can condense this more...
Edit 1: Switched if statements in inner loop to nested ? : operator
Edit 2: Stored range to intermediate variable (thanks Adrian), used stdin instead of CLI params (thanks for the clarification Jon), eliminated array in favor of direct output, fixed bug where an ending angle of 360 wouldn't display a line, removed some un-needed parentheses, used division for rounding instead of .round, used modulo instead of conditional add
Ruby, 168 characters
Requires Ruby 1.9 to work
s,e,r=gets.scan(/\d+/).map &:to_i;s/=45;e/=45;G=-r..r;G.map{|y|G.map{|x|a=Math.atan2(-y,x)/Math::PI*4%8;print x|y!=0?a==s||a==e%8?'-/|\\'[a%4]:a<s||a>e ?' ':8:?o};puts}
Readable version:
start, _end, radius = gets.scan(/\d+/).map &:to_i
start /= 45
_end /= 45
(-radius..radius).each {|y|
(-radius..radius).each {|x|
angle = Math.atan2(-y, x)/Math::PI * 4 % 8
print x|y != 0 ? angle==start || angle==_end%8 ? '-/|\\'[angle%4] : angle<start || angle>_end ? ' ' : 8 : ?o
}
puts
}
Perl - 388 characters
Since it wouldn't be fair to pose a challenge I couldn't solve myself, here's a solution that uses string substitution instead of trigonometric functions, and making heavy use of your friendly neighbourhood Perl's ability to treat barewords as strings. It's necessarily a little long, but perhaps interesting for the sake of uniqueness:
($x,$y,$r)=split/\D/,<>;for(0..$r-1){$t=$r-1-$_;
$a.=L x$_.D.K x$t.C.J x$t.B.I x$_."\n";
$b.=M x$t.F.N x$_.G.O x$_.H.P x$t."\n"}
$_=$a.E x$r.o.A x$r."\n".$b;$x/=45;$y/=45;$S=' ';
sub A{$v=$_[0];$x==$v||$y==$v?$_[1]:$x<$v&&$y>$v?x:$S}
sub B{$x<=$_[0]&&$y>$_[0]?x:$S}
#a=!$x||$y==8?'-':$S;
push#a,map{A$_,'\\'.qw(- / | \\)[$_%4]}1..7;
push#a,!$x?x:$S,map{B$_}1..7;
eval"y/A-P/".(join'',#a)."/";print
All newlines are optional. It's fairly straightforward:
Grab user input.
Build the top ($a) and bottom ($b) parts of the pattern.
Build the complete pattern ($_).
Define a sub A to get the fill character for an angle.
Define a sub B to get the fill character for a region.
Build an array (#a) of substitution characters using A and B.
Perform the substitution and print the results.
The generated format looks like this, for R = 4:
DKKKCJJJB
LDKKCJJBI
LLDKCJBII
LLLDCBIII
EEEEoAAAA
MMMFGHPPP
MMFNGOHPP
MFNNGOOHP
FNNNGOOOH
Where A-H denote angles and I-P denote regions.
(Admittedly, this could probably be golfed further. The operations on #a gave me incorrect output when written as one list, presumably having something to do with how map plays with $_.)
C# - 325 319 chars
using System;class P{static void Main(){var s=Console.ReadLine().Split(' ');
var d=s[0].Split('-');int l=s[1][0]-48,x,y,r,a=int.Parse(d[0]),b=int.Parse(d[1]);
for(y=l;y>=-l;y--)for(x=-l;x<=l;)Console.Write((x==0&&y==0?'o':a<=(r=((int)
(Math.Atan2(y,x)*57.3)+360)%360)&&r<b||r==b%360?
#"-/|\"[r/45%4]:' ')+(x++==l?"\n":""));}}
Newlines not significant.
Sample input/output
45-180 8
\||||||||////////
\\|||||||///////
\\\||||||//////
\\\\|||||/////
\\\\\||||////
\\\\\\|||///
\\\\\\\||//
\\\\\\\\|/
--------o
135-360 5
\
\\
\\\
\\\\
\\\\\
-----o-----
----/|\\\\\
---//||\\\\
--///|||\\\
-////||||\\
/////|||||\
Java - 304 chars
class A{public static void main(String[]a){String[]b=a[0].split("-");int e=new Integer(b[1]),r=new Integer(a[1]),g,x,y=r;for(;y>=-r;y--)for(x=-r;x<=r;)System.out.print((x==0&y==0?'o':new Integer(b[0])<=(g=((int)(Math.atan2(y,x)*57.3)+360)%360)&g<e|g==e%360?"-/|\\".charAt(g/45%4):' ')+(x++<r?"":"\n"));}}
More readable version:
class A{
public static void main(String[]a){
String[]b=a[0].split("-");
int e=new Integer(b[1]),r=new Integer(a[1]),g,x,y=r;
for(;y>=-r;y--)for(x=-r;x<=r;)System.out.print((
x==0&y==0
?'o'
:new Integer(b[0])<=(g=((int)(Math.atan2(y,x)*57.3)+360)%360)&g<e|g==e%360
?"-/|\\".charAt(g/45%4)
:' '
)+(x++<r?"":"\n"));
}
}
C (902 byte)
This doesn't use trigonometric functions (like the original perl version), so it's quite ``bloated''. Anyway, here is my first code-golf submission:
#define V(r) (4*r*r+6*r+3)
#define F for(i=0;i<r;i++)
#define C ;break;case
#define U p-=2*r+2,
#define D p+=2*r+2,
#define R *++p=
#define L *--p=
#define H *p='|';
#define E else if
#define G(a) for(j=0;j<V(r)-1;j++)if(f[j]==i+'0')f[j]=a;
#define O(i) for(i=0;i<2*r+1;i++){
main(int i,char**v){char*p,f[V(8)];
int j,m,e,s,x,y,r;p=*++v;x=atoi(p);while(*p!=45)p++;
char*h="0123";y=atoi(p+1);r=atoi(*++v);
for(p=f+2*r+1;p<f+V(r);p+=2*r+2)*p=10;
*(p-2*r-2)=0;x=x?x/45:x;y/=45;s=0;e=2*r;m=r;p=f;O(i)O(j)
if(j>e)*p=h[0];E(j>m)*p=h[1];E(j>s)*p=h[2];else*p=h[3];p++;}
if(i+1==r){h="7654";m--;e--;}E(i==r){s--;}E(i>r){s--;e++;}
else{s++;e--;}p++;}for(p=f+V(r)/2-1,i=0;i<r;i++)*++p=48;
for(i=0;i<8;i++)if(i>=x&&i<y){G(64);}else G(32);
y=y==8?0:y;q:p=f+V(r)/2-1;*p='o';switch(x){
C 0:F R 45 C 1:F U R 47 C 2:F U H C 3:F U L 92
C 4:F L 45 C 5:F D L 47 C 6:F D H C 7:F D R 92;}
if(y!=8){x=y;y=8;goto q;}puts(f);}
also, the #defines look rather ugly, but they save about 200 bytes so I kept them in, anyway. It is valid ANSI C89/C90 and compiles with very few warnings (two about atoi and puts and two about crippled form of main).
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
The puzzle
A little puzzle I heard while I was in high school went something like this...
The questioner would ask me to give him a number;
On hearing the number, the questioner would do some sort of transformation on it repeatedly (for example, he might say ten is three) until eventually arriving at the number 4 (at which point he would finish with four is magic).
Any number seems to be transformable into four eventually, no matter what.
The goal was to try to figure out the transformation function and then be able to reliably proctor this puzzle yourself.
The solution
The transformation function at any step was to
Take the number in question,
Count the number of letters in its English word representation, ignoring a hyphen or spaces or "and" (e.g., "ten" has 3 letters in it, "thirty-four" has 10 letters in it, "one hundred forty-three" has 20 letters in it).
Return that number of letters.
For all of the numbers I have ever cared to test, this converges to 4. Since "four" also has four letters in it, there would be an infinite loop here; instead it is merely referred to as magic by convention to end the sequence.
The challenge
Your challenge is to create a piece of code that will read a number from the user and then print lines showing the transformation function being repeatedly applied until "four is magic" is reached.
Specifically:
Solutions must be complete programs in and of themselves. They cannot merely be functions which take in a number-- factor in the input.
Input must be read from standard input. (Piping from "echo" or using input redirection is fine since that also goes from stdin)
The input should be in numeric form.
For every application of the transformation function, a line should be printed: a is b., where a and b are numeric forms of the numbers in the transformation.
Full stops (periods) ARE required!
The last line should naturally say, 4 is magic..
The code should produce correct output for all numbers from 0 to 99.
Examples:
> 4
4 is magic.
> 12
12 is 6.
6 is 3.
3 is 5.
5 is 4.
4 is magic.
> 42
42 is 8.
8 is 5.
5 is 4.
4 is magic.
> 0
0 is 4.
4 is magic.
> 99
99 is 10.
10 is 3.
3 is 5.
5 is 4.
4 is magic.
The winner is the shortest submission by source code character count which is also correct.
BONUS
You may also try to write a version of the code which prints out the ENGLISH NAMES for the numbers with each application of the transformation function. The original input is still numeric, but the output lines should have the word form of the number.
(Double bonus for drawing shapes with your code)
(EDIT) Some clarifications:
I do want the word to appear on both sides in all applicable cases, e.g. Nine is four. Four is magic.
I don't care about capitalization, though. And I don't care how you separate the word tokens, though they should be separated: ninety-nine is okay, ninety nine is okay, ninetynine is not okay.
I'm considering these a separate category for bonus competition with regard to the challenge, so if you go for this, don't worry about your code being longer than the numeric version.
Feel free to submit one solution for each version.
Perl, about 147 char
Loosely based on Platinum Azure's solution:
chop
($_.=
<>);#
u="433
5443554
366 887
798 866
555 766
"=~ /\d
/gx ;#4
sub r{4
-$_ ?$_
<20 ?$u
[$_ ]:(
$'? $u[
$'] :0)
+$u[18+$&]:magic}print"
$_ is ",$_=r(),'.'while
/\d
/x;
444
GolfScript - 101 96 93 92 91 90 94 86 bytes
90 → 94: Fixed output for multiples of 10.
94 → 86: Restructured code. Using base 100 to remove non-printable characters.
86 → 85: Shorter cast to string.
{n+~."+#,#6$DWOXB79Bd")base`1/10/~{~2${~1$+}%(;+~}%++=" is "\".
"1$4$4-}do;;;"magic."
Common Lisp 157 Chars
New more conforming version, now reading form standard input and ignoring spaces and hyphens:
(labels((g (x)(if(= x 4)(princ"4 is magic.")(let((n(length(remove-if(lambda(x)(find x" -"))(format nil"~r"x)))))(format t"~a is ~a.~%"x n)(g n)))))(g(read)))
In human-readable form:
(labels ((g (x)
(if (= x 4)
(princ "4 is magic.")
(let ((n (length (remove-if (lambda(x) (find x " -"))
(format nil "~r" x)))))
(format t"~a is ~a.~%" x n)
(g n)))))
(g (read)))
And some test runs:
>24
24 is 10.
10 is 3.
3 is 5.
5 is 4.
4 is magic.
>23152436
23152436 is 64.
64 is 9.
9 is 4.
4 is magic.
And the bonus version, at 165 chars:
(labels((g(x)(if(= x 4)(princ"four is magic.")(let*((f(format nil"~r"x))(n(length(remove-if(lambda(x)(find x" -"))f))))(format t"~a is ~r.~%"f n)(g n)))))(g(read)))
Giving
>24
twenty-four is ten.
ten is three.
three is five.
five is four.
four is magic.
>234235
two hundred thirty-four thousand two hundred thirty-five is forty-eight.
forty-eight is ten.
ten is three.
three is five.
five is four.
four is magic.
Python 2.x, 144 150 154 166 chars
This separates the number into tens and ones and sum them up. The undesirable property of the pseudo-ternary operator a and b or c that c is returned if b is 0 is being abused here.
n=input()
x=0x4d2d0f47815890bd2
while n-4:p=n<20and x/10**n%10or 44378/4**(n/10-2)%4+x/10**(n%10)%10+4;print n,"is %d."%p;n=p
print"4 is magic."
The previous naive version (150 chars). Just encode all lengths as an integer.
n=input()
while n-4:p=3+int('1yrof7i9b1lsi207bozyzg2m7sclycst0zsczde5oks6zt8pedmnup5omwfx56b29',36)/10**n%10;print n,"is %d."%p;n=p
print"4 is magic."
C - with number words
445 431 427 421 399 386 371 359* 356 354† 348 347 characters
That's it. I don't think I can make this any shorter.
All newlines are for readability and can be removed:
i;P(x){char*p=",one,two,three,four,five,six,sM,eight,nine,tL,elM,twelve,NP,4P,
fifP,6P,7P,8O,9P,twLQ,NQ,forQ,fifQ,6Q,7Q,8y,9Q,en,evL,thir,eL,tO,ty, is ,.\n,
4RmagicS,zero,";while(x--)if(*++p-44&&!x++)*p>95|*p<48?putchar(*p),++i:P(*p-48);
}main(c){for(scanf("%d",&c);c+(i=-4);P(34),P(c=i),P(35))P(c?c>19?P(c/10+18),
(c%=10)&&putchar(45):0,c:37);P(36);}
Below, it is somewhat unminified, but still pretty hard to read. See below for a more readable version.
i;
P(x){
char*p=",one,two,three,four,five,six,sM,eight,nine,tL,elM,twelve,NP,4P,fifP,6P,7P,8O,9P,twLQ,NQ,forQ,fifQ,6Q,7Q,8y,9Q,en,evL,thir,eL,tO,ty, is ,.\n,4RmagicS,zero,";
while(x--)
if(*++p-44&&!x++)
*p>95|*p<48?putchar(*p),++i:P(*p-48);
}
main(c){
for(scanf("%d",&c);c+(i=-4);P(34),P(c=i),P(35))
P(c?
c>19?
P(c/10+18),
(c%=10)&&
putchar(45)
:0,
c
:37);
P(36);
}
Expanded and commented:
int count; /* type int is assumed in the minified version */
void print(int index){ /* the minified version assumes a return type of int, but it's ignored */
/* see explanation of this string after code */
char *word =
/* 1 - 9 */
",one,two,three,four,five,six,sM,eight,nine,"
/* 10 - 19 */
"tL,elM,twelve,NP,4P,fifP,6P,7P,8O,9P,"
/* 20 - 90, by tens */
"twLQ,NQ,forQ,fifQ,6Q,7Q,8y,9Q,"
/* lookup table */
"en,evL,thir,eL,tO,ty, is ,.\n,4RmagicS,zero,";
while(index >= 0){
if(*word == ',')
index--;
else if(index == 0) /* we found the right word */
if(*word >= '0' && *word < 'a') /* a compression marker */
print(*word - '0'/*convert to a number*/);
else{
putchar(*word); /* write the letter to the output */
++count;
}
++word;
}
}
int main(int argc, char **argv){ /* see note about this after code */
scanf("%d", &argc); /* parse user input to an integer */
while(argc != 4){
count = 0;
if(argc == 0)
print(37/*index of "zero"*/);
else{
if(argc > 19){
print(argc / 10/*high digit*/ + 20/*offset of "twenty"*/ - 2/*20 / 10*/);
argc %= 10; /* get low digit */
if(argc != 0) /* we need a hyphen before the low digit */
putchar('-');
}
print(argc/* if 0, then nothing is printed or counted */);
}
argc = count;
print(34/*" is "*/);
print(argc); /* print count as word */
print(35/*".\n"*/);
}
print(36/*"four is magic.\n"*/);
}
About the encoded string near the beginning
The names of the numbers are compressed using a very simple scheme. Frequently used substrings are replaced with one-character indices into the name array. A "lookup table" of extra name entries is added to the end for substrings not used in their entirety in the first set. Lookups are recursive: entries can refer to other entries.
For instance, the compressed name for 11 is elM. The print() function outputs the characters e and l (lower-case 'L', not number '1') verbatim, but then it finds the M, so it calls itself with the index of the 29th entry (ASCII 'M' - ASCII '0') into the lookup table. This string is evL, so it outputs e and v, then calls itself again with the index of the 28th entry in the lookup table, which is en, and is output verbatim. This is useful because en is also used in eL for een (used after eight in eighteen), which is used in tO for teen (used for every other -teen name).
This scheme results in a fairly significant compression of the number names, while requiring only a small amount of code to decompress.
The commas at the beginning and end of the string account for the simplistic way that substrings are found within this string. Adding two characters here saves more characters later.
About the abuse of main()
argv is ignored (and therefore not declared in the compressed version), argc's value is ignored, but the storage is reused to hold the current number. This just saves me from having to declare an extra variable.
About the lack of #include
Some will complain that omitting #include <stdio.h> is cheating. It is not at all. The given is a completely legal C program that will compile correctly on any C compiler I know of (albeit with warnings). Lacking protoypes for the stdio functions, the compiler will assume that they are cdecl functions returning int, and will trust that you know what arguments to pass. The return values are ignored in this program, anyway, and they are all cdecl ("C" calling convention) functions, and we do indeed know what arguments to pass.
Output
Output is as expected:
0
zero is four.
four is magic.
1
one is three.
three is five.
five is four.
four is magic.
4
four is magic.
20
twenty is six.
six is three.
three is five.
five is four.
four is magic.
21
twenty-one is nine.
nine is four.
four is magic.
* The previous version missed the mark on two parts of the spec: it didn't handle zero, and it took input on the command line instead of stdin. Handling zeros added characters, but using stdin instead of command line args, as well as a couple of other optimzations saved the same number of characters, resulting in a wash.
† The requirements have been changed to make clear that the number word should be printed on both sides of " is ". This new version meets that requirement, and implements a couple more optimizations to (more than) account for the extra size necessary.
J, 107 112 characters
'4 is magic.',~}:('.',~":#{.,' is ',":#{:)"1]2&{.\.
(]{&(#.100 4$,#:3 u:ucp'䌵䐵吶梇禈榛ꪛ멩鮪鮺墊馊誙誩墊馊ꥺ겻곋榛ꪛ멩鮪鮺'))^:a:
(Newline for readability only)
Usage and output:
'4 is magic.',~}:('.',~":#{.,' is ',":#{:)"1]2&{.\.(]{&(#.100 4$,#:3 u:ucp'䌵䐵吶梇禈榛ꪛ멩鮪鮺墊馊誙誩墊馊ꥺ겻곋榛ꪛ멩鮪鮺'))^:a:12
12 is 6.
6 is 3.
3 is 5.
5 is 4.
4 is magic.
T-SQL, 413 451 499 chars
CREATE FUNCTION d(#N int) RETURNS int AS BEGIN
Declare #l char(50), #s char(50)
Select #l='0066555766',#s='03354435543668877987'
if #N<20 return 0+substring(#s,#N+1,1) return 0+substring(#l,(#N/10)+1,1) + 0+(substring(#s,#N%10+1,1))END
GO
CREATE proc M(#x int) as BEGIN
WITH r(p,n)AS(SELECT p=#x,n=dbo.d(#x) UNION ALL SELECT p=n,n=dbo.d(n) FROM r where n<>4)Select p,'is',n,'.' from r print '4 is magic.'END
(Not that I'm seriously suggesting you'd do this... really I just wanted to write a CTE)
To use:
M 95
Returns
p n
----------- ---- -----------
95 is 10.
10 is 3.
3 is 5.
5 is 4.
4 is magic.
Java (with boilerplate), 308 290 286 282 280 characters
class A{public static void main(String[]a){int i=4,j=0;for(;;)System.out.printf("%d is %s.%n",i=i==4?new java.util.Scanner(System.in).nextInt():j,i!=4?j="43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:".charAt(i)-48:"magic");}}
I'm sure Groovy would get rid of much of that.
Explanation and formatting (all comments, newlines and leading/trailing whitespace removed in count):
Reasonably straight forward, but
//boilerplate
class A{
public static void main(String[]a){
//i is current/left number, j right/next number. i=4 signals to start
//by reading input
int i=4,j=0;
for(;;)
//print in the form "<left> is <right>."
System.out.printf(
"%d is %s.%n",
i=i==4?
//<left>: if i is 4 <left> will be a new starting number
new java.util.Scanner(System.in).nextInt():
//otherwise it's the next val
j,
i!=4?
//use string to map number to its length (:;< come after 9 in ASCII)
//48 is value of '0'. store in j for next iteration
j="43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:".charAt(i)-48:
//i==4 is special case for right; print "magic"
"magic");
}
}
Edit: No longer use hex, this is less keystrokes
Windows PowerShell: 152 153 184 bytes
based on the previous solution, with more influence from other solutions
$o="03354435543668877988"
for($input|sv b;($a=$b)-4){if(!($b=$o[$a])){$b=$o[$a%10]-48+"66555766"[($a-$a%10)/10-2]}$b-=48-4*!$a
"$a is $b."}'4 is magic.'
C, 158 characters
main(n,c){char*d="03354435543668877988";for(scanf("%d",&n);n-4;n=c)printf("%d is %d.\n",n,c=n?n<19?d[n]-48:d[n%10]-"_,**+++)**"[n/10]:4);puts("4 is magic.");}
(originally based on Vlad's Python code, borrowed a trick from Tom Sirgedas' C++ solution to squeeze out a few more characters)
expanded version:
main(n, c) {
char *d = "03354435543668877988";
for (scanf("%d",&n); n-4; n = c)
printf("%d is %d.\n", n, c = n ? n<19 ? d[n]-48 : d[n%10] - "_,**+++)**"[n/10] : 4);
puts("4 is magic.");
}
Python, 129 133 137 148 chars
As a warm-up, here is my first version (improves couple of chars over previous best Python).
PS. After a few redactions now it is about twenty char's shorter:
n=input()
while n-4:p=(922148248>>n/10*3&7)+(632179416>>n%10*3&7)+(737280>>n&1)+4*(n<1);print n,'is %d.'%p;n=p
print'4 is magic.'
C#: 210 Characters.
Squished:
using C=System.Console;class B{static void Main(){int
x=0,y=int.Parse(C.ReadLine());while(x!=4)C.Write((x=y)+" is {0}.\n",x==4?"magic":""+(y=x==0?4:"03354435543668877988"[x<20?x:x%10]+"0066555766"[x/10]-96));}}
Expanded:
using C=System.Console;
class B
{
static void Main()
{
int x=0,y=int.Parse(C.ReadLine());
while(x!=4)
C.Write((x=y)+" is {0}.\n",
x==4?
"magic":
""+(y= x==0?
4:
"03354435543668877988"[x<20?x:x%10]+
"0066555766"[x/10]-96)
);
}
}
Tricks this approach uses:
Create a lookup table for number name lengths based on digits that appear in the number.
Use character array lookup on a string, and char arithmetic instead of a numeric array.
Use class name aliasing to short Console. to C.
Use the conditional (ternary) operator (?:) instead of if/else.
Use the \n with Write escape code instead of WriteLine
Use the fact that C# has a defined order of evaluation to allow assignments inside the Write function call
Use the assignment expressions to eliminate extra statements, and thus extra braces
Perl: 148 characters
(Perl: 233 181 212 206 200 199 198 185 179 149 148 characters)
Moved exceptions hash into unit array. This resulted in my being able to cut a lot of characters :-)
mobrule pointed out a nasty bug. Quick fix adds 31 characters, ouch!
Refactored for zero special case, mild golfing done as well.
Direct list access for single use rather than storing to array? Hell yes!
SO MUCH REFACTORING for just ONE bloody character. This, truly, is the life of a golfer. :-(
Oops, easy whitespace fix. 198 now.
Refactored some redundant code.
Last return keyword in r is unnecessary, shaved some more off.
Massive refactoring per comments; unfortunately I could only get it to 149 because I had to fix a bug that was present in both my earlier code and the commenters' versions.
Trying bareword "magic".
Let's get this ball rolling with a modest attempt in Perl.
#u=split'','4335443554366887798866555766';$_=<>;chop;print"$_ is ".($_=$_==4?0:$_<20?$u[$_]:($u[$_/10+18]+($_%10&&$u[$_%10]))or magic).".
"while$_
Tricks:
Too many!
JavaScript 1.8 (SpiderMonkey) - 153 Chars
l='4335443554366887798866555766'.split('')
for(b=readline();(a=+b)-4;print(a,'is '+b+'.'))b=a<20?l[a]:+l[18+a/10|0]+(a%10&&+l[a%10])
print('4 is magic.')
Usage: echo 42 | js golf.js
Output:
42 is 8.
8 is 5.
5 is 4.
4 is magic.
With bonus - 364 chars
l='zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty thirty fourty fifty sixty seventy eighty ninety'.split(' ')
z=function(a)a<20?l[a]:l[18+a/10|0]+(a%10?' '+l[a%10]:'')
for(b=+readline();(a=b)-4;print(z(a),'is '+z(b)+'.'))b=z(a).replace(' ','').length
print('four is magic.')
Output:
ninety nine is ten.
ten is three.
three is five.
five is four.
four is magic.
Haskell, 224 270 characters
o="43354435543668877988"
x!i=read[x!!i]
n x|x<20=o!x|0<1="0066555766"!div x 10+o!mod x 10
f x=zipWith(\a b->a++" is "++b++".")l(tail l)where l=map show(takeWhile(/=4)$iterate n x)++["4","magic"]
main=readLn>>=mapM putStrLn.f
And little more readable -
ones = [4,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,8,8]
tens = [0,0,6,6,5,5,5,7,6,6]
n x = if x < 20 then ones !! x else (tens !! div x 10) + (ones !! mod x 10)
f x = zipWith (\a b -> a ++ " is " ++ b ++ ".") l (tail l)
where l = map show (takeWhile (/=4) (iterate n x)) ++ ["4", "magic"]
main = readLn >>= mapM putStrLn . f
C++ Stdio version, minified: 196 characters
#include <cstdio>
#define P;printf(
char*o="43354435543668877988";main(int p){scanf("%d",&p)P"%d",p);while(p!=4){p=p<20?o[p]-48:"0366555966"[p/10]-96+o[p%10]P" is %d.\n%d",p,p);}P" is magic.\n");}
C++ Iostreams version, minified: 195 characters
#include <iostream>
#define O;std::cout<<
char*o="43354435543668877988";main(int p){std::cin>>p;O p;while(p!=4){p=p<20?o[p]-48:"0366555966"[p/10]-96+o[p%10]O" is "<<p<<".\n"<<p;}O" is magic.\n";}
Original, un-minified: 344 characters
#include <cstdio>
int ones[] = { 4, 3, 3, 5, 4, 4, 3, 5, 5, 4, 3, 6, 6, 8, 8, 7, 7, 9, 8, 8 };
int tens[] = { 0, 3, 6, 6, 5, 5, 5, 9, 6, 6 };
int n(int n) {
return n<20 ? ones[n] : tens[n/10] + ones[n%10];
}
int main(int p) {
scanf("%d", &p);
while(p!=4) {
int q = n(p);
printf("%i is %i\n", p, q);
p = q;
}
printf("%i is magic\n", p);
}
Delphi: 329 characters
Single Line Version:
program P;{$APPTYPE CONSOLE}uses SysUtils;const S=65;A='EDDFEEDFFEDGGIIHHJII';B='DGGFFFJGG';function Z(X:Byte):Byte;begin if X<20 then Z:=Ord(A[X+1])-S else Z:=(Ord(B[X DIV 10])-S)+Z(X MOD 10)end;var X,Y:Byte;begin Write('> ');ReadLn(X);repeat Y:=Z(X);WriteLn(Format('%d is %d.',[X,Y]));X:=Y;until X=4;WriteLn('4 is magic.');end.
Formated:
program P;
{$APPTYPE CONSOLE}
uses
SysUtils;
const
S = 65;
A = 'EDDFEEDFFEDGGIIHHJII';
B = 'DGGFFFJGG';
function Z(X:Byte):Byte;
begin
if X<20
then Z := Ord(A[X+1])-S
else Z := (Ord(B[X DIV 10])-S) + Z(X MOD 10);
end;
var
X,Y: Byte;
begin
Write('> ');
ReadLn(X);
repeat
Y:=Z(X);
WriteLn(Format('%d is %d.' , [X,Y]));
X:=Y;
until X=4;
WriteLn('4 is magic.');
end.
Probably room for some more squeezing... :-P
C# 314 286 283 274 289 273 252 chars.
Squished:
252
Normal:
using C = System.Console;
class P
{
static void Main()
{
var x = "4335443554366877798866555766";
int m, o, v = int.Parse(C.ReadLine());
do {
C.Write("{0} is {1}.\n", o = v, v == 4 ? (object)"magic" : v = v < 20 ? x[v] - 48 : x[17 + v / 10] - 96 + ((m = v % 10) > 0 ? x[m] : 48));
} while (o != 4);
C.ReadLine();
}
}
Edit Dykam: Did quite some carefull insertions and changes:
Changed the l.ToString() into a cast to object of the string "magic".
Created a temporary variable o, so I could move the break outside the for loop, that is, resulting in a do-while.
Inlined the o assignment, aswell the v assignment, continueing in inserting the calculation of l in the function arguments altogether, removing the need for l. Also inlined the assignment of m.
Removed a space in int[] x, int[]x is legit too.
Tried to transform the array into a string transformation, but the using System.Linq was too much to make this an improvement.
Edit 2 Dykam
Changed the int array to a char array/string, added proper arithmics to correct this.
Lua, 176 Characters
o={[0]=4,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,8,8}t={3,6,6,5,5,5,7,6,6}n=0+io.read()while n~=4 do a=o[n]or o[n%10]+t[(n-n%10)/10]print(n.." is "..a..".")n=a end print"4 is magic."
or
o={[0]=4,3,3,5,4,4
,3,5,5,4,3,6,6,8,8
,7,7,9,8,8}t={3,6,
6,5,5,5,7,6,6}n=
0+io.read()while
n ~= 4 do a= o[n
]or o[n%10]+t[(n
-n%10)/10]print(
n.." is "..a.."." )n=a
end print"4 is magic."
C - without number words
180 175* 172 167 characters
All newlines are for readability and can be removed:
i;V(x){return"\3#,#6$:WOXB79B"[x/2]/(x%2?1:10)%10;}main(c){for(scanf("%d",&c);
c-4;)i=c,printf("%d is %d.\n",i,c=c?c>19?V(c/10+19)+V(c%10):V(c):4);puts(
"4 is magic.");}
Slightly unminified:
i;
V(x){return"\3#,#6$:WOXB79B"[x/2]/(x%2?1:10)%10;}
main(c){
for(scanf("%d",&c);c-4;)
i=c,
printf("%d is %d.\n",i,c=c?c>19?V(c/10+19)+V(c%10):V(c):4);
puts("4 is magic.");
}
* The previous version missed the mark on two parts of the spec: it didn't handle zero, and it took input on the command line instead of stdin. Handling zero added characters, but using stdin instead of command line args saved even more, resulting in a net savings.
perl, 123 122 characters
Just realized that there is no requirement to output to STDOUT, so output to STDERR instead and knock off another character.
#u='0335443554366887798866555766'=~/./g;$_+=<>;warn"$_ is ",$_=$_-4?$_<20?$u[$_]||4:$u[chop]+$u[$_+18]:magic,".\n"until/g/
And, a version that returns spelled out numbers:
279 278 276 280 characters
#p=(Thir,Four,Fif,Six,Seven,Eigh,Nine);#n=("",One,Two,Three,Four,Five,#p[3..6],Ten,Eleven,Twelve,map$_.teen,#p);s/u//for#m=map$_.ty,Twen,#p;$n[8].=t;sub n{$n=shift;$n?$n<20?$n[$n]:"$m[$n/10-2] $n[$n%10]":Zero}$p+=<>;warnt$m=n($p)," is ",$_=$p-4?n$p=()=$m=~/\w/g:magic,".\n"until/c/
While that meets the spec, it is not 100% well formatted. It returns an extra space after numbers ending in zero. The spec does say:
"I don't care how you separate the word tokens, though they should be separated"
That's kind of weaselly though.
A more correct version at
282 281 279 283 characters
#p=(Thir,Four,Fif,Six,Seven,Eigh,Nine);#n=("\x8",One,Two,Three,Four,Five,#p[3..6],Ten,Eleven,Twelve,map$_.teen,#p);s/u//for#m=map$_.ty,Twen,#p;$n[8].=t;sub n{$n=shift;$n?$n<20?$n[$n]:"$m[$n/10-2]-$n[$n%10]":Zero}$p+=<>;warn$m=n($p)," is ",$_=$p-4?n$p=()=$m=~/\w/g:magic,".\n"until/c/
Python:
#!/usr/bin/env python
# Number of letters in each part, we don't count spaces
Decades = ( 0, 3, 6, 6, 6, 5, 5, 7, 6, 6, 0 )
Smalls = ( 0, 3, 3, 5, 4, 4, 3, 5, 5, 4 )
Teens = ( 6, 6, 8, 8, 7, 7, 9, 8, 8 )
def Count(n):
if n > 10 and n < 20: return Teens[n-11]
return Smalls[n % 10 ] + Decades [ n / 10 ]
N = input()
while N-4:
Cnt = Count(N)
print "%d is %d" % ( N, Cnt)
N = Cnt
print "4 is magic"
C++, 171 characters (#include omitted)
void main(){char x,y,*a="03354435543668877988";scanf("%d",&x);for(;x-4;x=y)y=x?x<19?a[x]-48:"_466555766"[x/10]+a[x%10]-96:4,printf("%d is %d.\n",x,y);puts("4 is magic.");}
Ruby, 164 characters
n=gets.to_i;s="03354435543668877987";if n==0;puts"0 is 4.";else;puts"#{n} is #{n=(n<20)?s[n]-48:"0066555766"[n/10]-48+s[n%10]-48}." until n==4;end;puts"4 is magic."
decoded:
n = gets.to_i
s = "03354435543668877987"
if n == 0
puts "0 is 4."
else
puts "#{n} is #{n = (n < 20) ? s[n] - 48 : "0066555766"[n / 10] - 48 + s[n % 10] - 48}." until n == 4
end
puts "4 is magic."
Lua 185 190 199
added periods, added io.read, removed ()'s on last print
n=io.read();while(n~=4)do m=('43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:'):sub(n+1):byte()-48;print(n,' is ',m,'.')n=m;end print'4 is magic.'
with line breaks
n=io.read()
while (n~=4) do
m=('43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:'):sub(n+1):byte()-48;
print(n,' is ',m,'.')
n=m;
end
print'4 is magic.'
PhP Code
function get_num_name($num){
switch($num){
case 1:return 'one';
case 2:return 'two';
case 3:return 'three';
case 4:return 'four';
case 5:return 'five';
case 6:return 'six';
case 7:return 'seven';
case 8:return 'eight';
case 9:return 'nine';
}
}
function num_to_words($number, $real_name, $decimal_digit, $decimal_name){
$res = '';
$real = 0;
$decimal = 0;
if($number == 0)
return 'Zero'.(($real_name == '')?'':' '.$real_name);
if($number >= 0){
$real = floor($number);
$decimal = number_format($number - $real, $decimal_digit, '.', ',');
}else{
$real = ceil($number) * (-1);
$number = abs($number);
$decimal = number_format($number - $real, $decimal_digit, '.', ',');
}
$decimal = substr($decimal, strpos($decimal, '.') +1);
$unit_name[1] = 'thousand';
$unit_name[2] = 'million';
$unit_name[3] = 'billion';
$unit_name[4] = 'trillion';
$packet = array();
$number = strrev($real);
$packet = str_split($number,3);
for($i=0;$i<count($packet);$i++){
$tmp = strrev($packet[$i]);
$unit = $unit_name[$i];
if((int)$tmp == 0)
continue;
$tmp_res = '';
if(strlen($tmp) >= 2){
$tmp_proc = substr($tmp,-2);
switch($tmp_proc){
case '10':
$tmp_res = 'ten';
break;
case '11':
$tmp_res = 'eleven';
break;
case '12':
$tmp_res = 'twelve';
break;
case '13':
$tmp_res = 'thirteen';
break;
case '15':
$tmp_res = 'fifteen';
break;
case '20':
$tmp_res = 'twenty';
break;
case '30':
$tmp_res = 'thirty';
break;
case '40':
$tmp_res = 'forty';
break;
case '50':
$tmp_res = 'fifty';
break;
case '70':
$tmp_res = 'seventy';
break;
case '80':
$tmp_res = 'eighty';
break;
default:
$tmp_begin = substr($tmp_proc,0,1);
$tmp_end = substr($tmp_proc,1,1);
if($tmp_begin == '1')
$tmp_res = get_num_name($tmp_end).'teen';
elseif($tmp_begin == '0')
$tmp_res = get_num_name($tmp_end);
elseif($tmp_end == '0')
$tmp_res = get_num_name($tmp_begin).'ty';
else{
if($tmp_begin == '2')
$tmp_res = 'twenty';
elseif($tmp_begin == '3')
$tmp_res = 'thirty';
elseif($tmp_begin == '4')
$tmp_res = 'forty';
elseif($tmp_begin == '5')
$tmp_res = 'fifty';
elseif($tmp_begin == '6')
$tmp_res = 'sixty';
elseif($tmp_begin == '7')
$tmp_res = 'seventy';
elseif($tmp_begin == '8')
$tmp_res = 'eighty';
elseif($tmp_begin == '9')
$tmp_res = 'ninety';
$tmp_res = $tmp_res.' '.get_num_name($tmp_end);
}
break;
}
if(strlen($tmp) == 3){
$tmp_begin = substr($tmp,0,1);
$space = '';
if(substr($tmp_res,0,1) != ' ' && $tmp_res != '')
$space = ' ';
if($tmp_begin != 0){
if($tmp_begin != '0'){
if($tmp_res != '')
$tmp_res = 'and'.$space.$tmp_res;
}
$tmp_res = get_num_name($tmp_begin).' hundred'.$space.$tmp_res;
}
}
}else
$tmp_res = get_num_name($tmp);
$space = '';
if(substr($res,0,1) != ' ' && $res != '')
$space = ' ';
$res = $tmp_res.' '.$unit.$space.$res;
}
$space = '';
if(substr($res,-1) != ' ' && $res != '')
$space = ' ';
if($res)
$res .= $space.$real_name.(($real > 1 && $real_name != '')?'s':'');
if($decimal > 0)
$res .= ' '.num_to_words($decimal, '', 0, '').' '.$decimal_name.(($decimal > 1 && $decimal_name != '')?'s':'');
return ucfirst($res);
}
//////////// testing ////////////////
$str2num = 12;
while($str2num!=4){
$str = num_to_words($str2num, '', 0, '');
$str2num = strlen($str)-1;
echo $str . '=' . $str2num .'<br/>';
if ($str2num == 4)
echo 'four is magic';
}
////// Results /////////
Twelve =6
Six =3
Three =5
Five =4
four is magic
Perl - 130 chars
5.12.1 (130 chars) 121 123 132 136 140
# 1 2 3 4 5 6 7 8 9 100 11 12 13 14
#23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123
#u='4335443554366887798866555766'=~/./g;$_=pop;say"$_ is ",$_=$_-4?$_<20?$u[$_]:$u[$_/10+18]+(($_%=10)&&$u[$_]):magic,"."until/\D/
5.10.1 (134 chars) 125 127 136 140 144
# 1 2 3 4 5 6 7 8 9 100 11 12 13 14
#23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1234
#u='4335443554366887798866555766'=~/./g;$_=pop;print"$_ is ",$_=$_-4?$_<20?$u[$_]:$u[$_/10+18]+(($_%=10)&&$u[$_]):magic,".\n"until/\D/
Change History:
20100714:2223 - reverted change at the attention of mobrule, but ($_%10&&$u[$_%10]) → (($_%=10)&&$u[$_]), which is the same # of chars, but I did it in case someone might see a way to improve it
20100714:0041 - split//,'...' → '...'=~/./g
20100714:0025 - ($_%10&&$u[$_%10]) → $u[$_%10]
20100713:2340 - while$_ → until/\D/ + removed unnecessary parentheses
20100713:xxxx - $=<>;chop; → $_=pop; - courtesy to mobrule
Note: I was tired of improving others' answers in comments, so now I'm being greedy and can just add my changes here :) This is a split off from Platinum Azure's answer - credit in part to Hobbs, mobrule, and Platinum Azure.
Shameless Perl with Number Words (329 characters)
Adapted fairly directly from P Daddy's C code, with some tweaks to p() to make it do the same thing using Perl primitives instead of C ones, and a mostly-rewritten mainloop. See his for an explanation. Newlines are all optional.
#t=(qw(zero one two three four five six sM eight nine
tL elM twelve NP 4P fifP 6P 7P 8O 9P twLQ NQ forQ fifQ
6Q 7Q 8y 9Q en evL thir eL tO ty 4SmagicT)," is ",".\n");
sub p{local$_=$t[pop];1while s/[0-Z]/$t[-48+ord$&]/e;
print;length}$_=<>;chop;while($_-4){
$_=($_>19?(p($_/10+18),$_&&print("-"),$_%=10)[0]:0)+p$_;
p 35;p$_;p 36}p 34
Side note: it's too bad that perl print just returns true/false; if it returned a count it would save me 7 strokes.
Ruby, 141 chars:
n=gets.to_i;m="4335443554366887798866555766";loop{s=n;n=n>20?m[18+n/10]+m[n%10]-96: m[n]-48;puts"#{s} is #{n==s ? 'magic': n}.";n==s &&break}
while(true)
{
string a;
ReadLine(a)
WriteLine(4);
}
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
This is inspired by/taken from this thread: http://www.allegro.cc/forums/thread/603383
The Problem
Assume the user gives you a numeric input ranging from 1 to 7. Input should be taken from the console, arguments are less desirable.
When the input is 1, print the following:
***********
*********
*******
*****
***
*
Values greater than one should generate multiples of the pattern, ending with the one above, but stacked symmetrically. For example, 3 should print the following:
*********** *********** ***********
********* ********* *********
******* ******* *******
***** ***** *****
*** *** ***
* * *
*********** ***********
********* *********
******* *******
***** *****
*** ***
* *
***********
*********
*******
*****
***
*
Bonus points if you print the reverse as well.
*********** ***********
********* *********
******* *******
***** *****
*** ***
* *
***********
*********
*******
*****
***
*
*
***
*****
*******
*********
***********
* *
*** ***
***** *****
******* *******
********* *********
*********** ***********
Can we try and keep it to one answer per language, that we all improve on?
Assembler, 165 bytes assembled
Build Instructions
Download A86 from here
Add a reference to the A86 executable into your DOS search path
Paste the code below into a text file (example: triforce.asm)
Invoke the assembler: a86 triforce.asm
This will create a .COM file called triforce.com
Type triforce to run
This was developed using the standard WinXP DOS box (Start->Programs->Accessories->Command Prompt). It should work with other DOS emulators.
Assemble using A86 and requires WinXP DOS box to run the .COM file it produces. Press 'q' to exit, keys 1-7 to draw the output.
l20:mov ah,7
int 21h
cmp al,'q'
je ret
sub al,'0'
cmp al,1
jb l20
cmp al,7
ja l20
mov [l0-1],al
mov byte ptr [l7+2],6
jmp $+2
mov ah,2
mov ch,0
mov bh,3
l0:mov bl,1
l1:mov dh,0
l3:cmp dh,ch
je l2
mov dl,32
int 21h
inc dh
jmp l3
ret
l2:mov dh,bh
l6:mov cl,12
l5:mov dl,42
cmp cl,bl
ja l4
mov dl,32
cmp dh,1
je l21
l4:int 21h
dec cl
jnz l5
l21:dec dh
jnz l6
mov dl,10
int 21h
mov dl,13
int 21h
l10:inc ch
l9:add bl,2
l7:cmp ch,6
jne l1
l13:add byte ptr [l7+2],6
l11:dec bh
l12:cmp bh,0
jne l0
xor byte ptr [l0+1],10
xor byte ptr [l9+1],40
xor byte ptr [l10+1],8
xor byte ptr [l13+1],40
sub byte ptr [l7+2],12
mov dh,[l0-1]
inc dh
xor [l12+2],dh
xor byte ptr [l11+1],8
xor byte ptr [l1+1],1
inc bh
cmp byte ptr [l0+1],11
je l0
jmp l20
It uses lots of self-modifying code to do the triforce and its mirror, it even modifies the self-modifying code.
GolfScript - 43 chars
~:!6*,{:^' '
*'*'12*' '
^6%.+)*+
-12>!^
6/-*
n}
/
~:!6*,{:^' '*'*'12*' '^6%.+)*+-12>!^6/-*n}/
48 Chars for the bonus
~:!6*,.-1%+{
:^' '*'*'12
*' '^6%.+
)*+-12>
!^6/-
*n}
/
~:!6*,.-1%+{:^' '*'*'12*' '^6%.+)*+-12>!^6/-*n}/
Python - 77 Chars
n=input()
for k in range(6*n):print' '*k+('*'*12+' '*(k%6*2+1))[-12:]*(n-k/6)
n=input()
for k in range(6*n):j=1+k%6*2;print' '*k+('*'*(12-j)+' '*j)*(n-k/6)
89 Chars for the bonus
n=input();R=range(6*n)
for k in R+R[::-1]:print' '*k+('*'*11+' '*11)[k%6*2:][:12]*(n-k/6)
114 Chars Version just using string replacements
u,v=' *';s=(v*11+u)*input()
while s.strip():print s;s=u+s.replace(*((v*2+u,u*3),(v*1+u*10,v*11))[' * 'in s])[:-2]
Unk Chars all in one statement, should work w/ 2.x and 3.x. The enumerate() is to allow the single input() to work for both places you need to use it.
print ('\n'.join('\n'.join(((' '*(6*n))+' '.join(('%s%s%s'%(' '*(5-x),'*'*(2*x+1),' '*(5-x)) for m in range(i + 1)))) for x in range(5,-1,-1)) for n, i in enumerate(range(int(input())-1,-1,-1))))
Yet Another Method
def f(n): print '\n'.join(' '*6*(n-r)+(' '*(5-l)+'*'*(l*2+1)+' '*(5-l)+' ')*r for r in xrange(1, n+1) for l in xrange(6))
f(input())
Ruby - 74 Chars
(6*n=gets.to_i).times{|k|puts' '*k+('*'*(11-(j=k%6*2))+' '*(j+1))*(n-k/6)}
COBOL - 385 Chars
$ cobc -free -x triforce.cob && echo 7| ./triforce
PROGRAM-ID.P.DATA DIVISION.WORKING-STORAGE SECTION.
1 N PIC 9.
1 M PIC 99.
1 value '0100***********'.
2 I PIC 99.
2 K PIC 99.
2 V PIC X(22).
2 W PIC X(99).
PROCEDURE DIVISION.ACCEPT N
COMPUTE M=N*6
PERFORM M TIMES
DISPLAY W(1:K)NO ADVANCING
PERFORM N TIMES
DISPLAY V(I:12)NO ADVANCING
END-PERFORM
DISPLAY ''
ADD 2 TO I
IF I = 13 MOVE 1 TO I ADD -1 TO N END-IF
ADD 1 TO K
END-PERFORM.
K could be returned to outside the group level. An initial value of zero for a numeric with no VALUE clause is compiler-implementation dependent, as is an initial value of space for an alpha-numeric field (W has been cured of this, at no extra character cost). Moving K back would save two characters. -free is compiler-dependant as well, so I'm probably being over-picky.
sed, 117 chars
s/$/76543210/
s/(.).*\1//
s/./*********** /gp
:
s/\*(\**)\*/ \1 /gp
t
:c
s/\* {11}\*/ ************/
tc
s/\* / /p
t
Usage: $ echo 7 | sed -rf this.sed
First attempt; improvements could probably be made...
Ruby 1.9 - 84 characters :
v=gets.to_i
v.times{|x|6.times{|i|puts' '*6*x+(' '*i+'*'*(11-2*i)+' '*i+' ')*(v-x)}}
Perl - 72 chars
die map$"x$_.("*"x(12-($l=1+$_%6*2)).$"x$l)x($n-int$_/6).$/,0..6*($n=<>)
78 chars
map{$l=$_%6*2;print$"x$_,("*"x(11-$l).$"x$l.$")x($n-int$_/6),$/}0..6*($n=<>)-1
87 chars
$n=<>;map{$i=int$_/6;$l=$_%6*2;print$"x$_,("*"x(11-$l).$"x$l.$")x($n-$i),$/}(0..6*$n-1)
97 chars
$n=<>;map{$i=int$_/6;$l=$_%6;print$"x(6*$i),($"x$l."*"x(11-2*$l).$"x$l.$")x($n-$i),$/}(0..6*$n-1)
108 chars
$n=<>;map{$i=int$_/6;$l=$_%6;print ""." "x(6*$i),(" "x$l."*"x(11-2*$l)." "x$l." ")x($n-$i),"\n";}(0..6*$n-1)
Powershell, 78 characters
0..(6*($n=read-host)-1)|%{" "*$_+("*"*(12-($k=1+$_%6*2))+" "*$k)*(.4+$n-$_/6)}
Bonus, 92 characters
$a=0..(6*($n=read-host)-1)|%{" "*$_+("*"*(12-($k=1+$_%6*2))+" "*$k)*(.4+$n-$_/6)}
$a
$a|sort
The output is stored in an array of strings, $a, and the reverse is created by sorting the array. We could, of course, just reverse the array, but it would be more characters to type :)
Haskell - 131 138 142 143 Chars
(⊗)=replicate
z o=[concat$(6*n+m)⊗' ':(o-n)⊗((11-m-m)⊗'*'++(1+m+m)⊗' ')|n<-[0..o-1],m<-[0..5]]
main=getLine>>=mapM_ putStrLn.z.read
This one is longer (146 148 chars) at present, but an interesting, alternate line of attack:
(⊗)=replicate
a↑b|a>b=' ';_↑_='*'
z o=[map(k↑)$concat$(6*n)⊗' ':(o-n)⊗"abcdefedcba "|n<-[0..o-1],k<-"abcdef"]
main=getLine>>=mapM_ putStrLn.z.read
FORTRAN - 97 Chars
Got rid of the #define and saved 8 bytes thanks to implict loops!
$ f95 triforce.f95 -o triforce && echo 7 | ./triforce
READ*,N
DO K=0,N*6
M=2*MOD(K,6)
PRINT*,(' ',I=1,K),(('*',I=M,10),(' ',I=0,M),J=K/6+1,N)
ENDDO
END
125 bytes for the bonus
READ*,N
DO L=1,N*12
K=L+5
If(L>N*6)K=N*12-L+6
M=2*MOD(K,6)
PRINT"(99A)",(32,I=7,K),((42,I=M,10),(32,I=0,M),J=K/6,N)
ENDDO
END
FORTRAN - 108 Chars
#define R REPEAT
READ*,N
DO I=0,6*N
J=MOD(I,6)*2
PRINT*,R(' ',I)//R(R('*',11-J)//R(' ',J+1),N-I/6)
ENDDO
END
JavaScript 1.8 - SpiderMonkey - 118 chars
N=readline()
function f(n,c)n>0?(c||' ')+f(n-1,c):''
for(i=0;i<N*6;i++)print(f(i)+f(N-i/6,f(11-(z=i%6*2),'*')+f(z+1)))
w/ bonus - 151 chars
N=readline()
function f(n,c)n>0?(c||' ')+f(n-1,c):''
function l(i)print(f(i)+f(N-i/6,f(11-(z=i%6*2),'*')+f(z+1)))
for(i=0;i<N*6;i++)l(i)
for(;i--;)l(i)
Usage: js thisfile.js
JavaScript - In Browser - 154 characters
N=prompt()
function f(n,c){return n>0?(c||' ')+f(n-1,c):''}
s='<pre>'
for(i=0;i<N*6;i++)s+=f(i)+f(N-i/6,f(11-(z=i%6*2),'*')+f(z+1))+'\n'
document.write(s)
The non-obfuscated version (before optimizations by gnarf):
var N = prompt();
var S = ' ';
function fill(c, n) {
for (ret=''; n--;)
ret += c;
return ret;
}
var str = '<pre>';
for (i=0; i<N*6; i++) {
str += fill(S, i);
for (j=0; j<N-i/6; j++)
str += fill('*', 11-i%6*2) + fill(S, i%6*2+1);
str += '\n';
}
document.write(str);
Here's a different algorithm that uses replace() to go from one line to the next of each line of a triangle row:
161 characters
N=readline()
function f(n,c){return n>0?(c||' ')+f(n-1,c):''}l=0
for(i=N;i>0;){r=f(i--,f(11,'*')+' ');for(j=6;j--;){print(f(l++)+r)
r=r.replace(/\*\* /g,' ')}}
F#, 184 181 167 151 147 143 142 133 chars
let N,r=int(stdin.ReadLine()),String.replicate
for l in[0..N*6-1]do printfn"%s%s"(r l" ")(r(N-l/6)((r(11-l%6*2)"*")+(r(l%6*2+1)" ")))
Bonus, 215 212 198 166 162 158 157 148 chars
let N,r=int(stdin.ReadLine()),String.replicate
for l in[0..N*6-1]#[N*6-1..-1..0]do printfn"%s%s"(r l" ")(r(N-l/6)((r(11-l%6*2)"*")+(r(l%6*2+1)" ")))
C - 120 Chars
main(w,i,x,y){w=getchar()%8*12;for(i=0;i<w*w/2;)y=i/w,x=i++%w,putchar(x>w-2?10:x<y|w-x-1<y|(x-y)%12>=11-2*(y%6)?32:42);}
Note that this solution prints some trailing spaces (which is okay, right?). It also relies on relational operators having higher precedence than bitwise OR, saving two characters.
124 Chars
main(n,i,k){n=getchar()&7;for(k=0;k<6*n;k++,putchar(10))for(i=-k-1;++i<12*n-2*k-1;putchar(32+10*(i>=0&&(11-i%12>2*k%12))));}
C - 177 183 Chars
#define P(I,C)for(m=0;m<I;m++)putchar(C)
main(t,c,r,o,m){scanf("%d",&t);for(c=t;c>0;c--)for(r=6;r>0;r--){P((t-c)*6+6-r,32);for(o=0;o<c;o++){P(r*2-1,42);P(13-r*2,32);}puts("");}}
C - 222 243 Chars (With Bonus Points)
#define P(I,C)for(m=0;m<I;m++)putchar(C)
main(t,c,r,o,m){scanf("%d",&t);for(c=t-1;-c<2+t;c-=1+!c)for(r=c<0?1:6;c<0?r<7:r>0;r+=c<0?1:-1){P((t-abs(c+1))*6+6-r,32);for(o=0;o<abs(c+1);o++){P(r*2-1,42);P(13-r*2,32);}puts("");}}
This is my first Code Golf submission as well!
Written in C
Bonus points (492 chars):
p(char *t, int c, int s){int i=0;for(;i<s;i++)printf(" ");for(i=0;i<c;i++)printf("%s",t);printf("\n");}main(int a, char **v){int i=0;int k;int c=atoi(v[1]);for(;i<c;i++){p("*********** ",c-i,i);p(" ********* ",c-i,i);p(" ******* ",c-i,i);p(" ***** ",c-i,i);p(" *** ",c-i,i);p(" * ",c-i,i);}for(i=0;i<c;i++){k=c-i-1;p(" * ",1+i,k);p(" *** ",1+i,k);p(" ***** ",1+i,k);p(" ******* ",1+i,k);p(" ********* ",1+i,k);p("*********** ",i+1,k);}}
Without bonus points (322 chars):
p(char *t, int c, int s){int i=0;for(;i<s;i++)printf(" ");for(i=0;i<c;i++)printf("%s",t);printf("\n");}main(int a, char **v){int i=0;int k;int c=atoi(v[1]);for(;i<c;i++){p("*********** ",c-i,i);p(" ********* ",c-i,i);p(" ******* ",c-i,i);p(" ***** ",c-i,i);p(" *** ",c-i,i);p(" * ",c-i,i);}}
First time posting, too!
Lua, 121 chars
R,N,S=string.rep,io.read'*n',' 'for i=0,N-1 do for j=0,5 do X=R(S,j)print(R(S,6*i)..R(X..R('*',11-2*j)..X..S,N-i))end end
123
R,N,S=string.rep,io.read'*n',' 'for i=0,N-1 do for j=0,5 do print(R(S,6*i)..R(R(S,j)..R('*',11-2*j)..R(S,j)..S,N-i))end end
PHP, 153
<?php $i=fgets(STDIN);function r($n,$c=' '){return$n>0?$c.r($n-1,$c):'';}for($l=0;$l<$i*6;){$z=$l%6*2;echo r($l).r($i-$l++/6,r(11-$z,'*').r($z+1))."\n";}
with Bonus, 210
<?php $i=fgets(STDIN);function r($n,$c=' '){return$n>0?$c.r($n-1,$c):'';}$o=array();for($l=0;$l<$i*6;){$z=$l%6*2;$o[]=r($l).r($i-$l++/6,r(11-$z,'*').r($z+1));}print join("\n",array_merge($o,array_reverse($o)));
dc 105 chars
123 129 132 139 141
[rdPr1-d0<P]sP?sn
0sk[1lk6%2*+sj32lkd0<Plnlk6/-si
[[*]12lj-d0<P32ljd0<Pli1-dsi0<I]dsIx
10Plk1+dskln6*>K]dsKx
Mathematica, 46 characters
The answer prints sideways.
TableForm#{Table["*",{l,#},{l},{j,6},{2j-1}]}&
HyperTalk - 272 chars
function triforce n
put"******" into a
put n*6 into h
repeat with y=0 to h-1
put" " after s
put char 1 to y of s after t
repeat n-y div 6
get y mod 6*2
put char 1 to 11-it of (a&a)&&char 1 to it of s after t
end repeat
put return after t
end repeat
return t
end triforce
Indentation is neither needed nor counted (HyperCard automatically adds it).
Miscellanea:
Since there is no notion of console or way to access console arguments in HyperCard 2.2 (that I know of), a function is given instead. It can be invoked with:
on mouseUp
ask "Triforce: "
put triforce(it) into card field 1
end mouseUp
To use this, a card field would be created and set to a fixed-width font. Using HyperCard's answer command would display a dialog with the text, but it doesn't work because:
The answer dialog font (Chicago) is not fixed-width.
The answer command refuses to display long text (even triforce(2) is too long).
Common Lisp, 150 characters:
(defun f(n o)(unless(= n 0)(dotimes(x 6)(format t"~v#{~a~:*~}~-1:*~v#{~?~2:*~}~%"
o" "n"~11#: "(list(- 11(* 2 x))#\*)))(f(1- n)(+ 6 o))))
77 char alternative python solution based on gnibbler's:
n=input()
k=0
exec"print' '*k+('*'*12+' '*(k%6*2+1))[-12:]*(n-k/6);k+=1;"*6*n
Amazingly the bonus came out exactly the same also (101 chars, oh well)
n=input()
l=1
k=0
s="print' '*k+('*'*12+' '*(k%6*2+1))[-12:]*(n-k/6);k+=l;"*6*n
exec s+'l=-1;k-=1;'+s
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
In Google Code Jam 2009, Round 1B, there is a problem called Decision Tree that lent itself to rather creative solutions.
Post your shortest solution; I'll update the Accepted Answer to the current shortest entry on a semi-frequent basis, assuming you didn't just create a new language just to solve this problem. :-P
Current rankings:
107 Perl
121 PostScript (binary)
132 Ruby
154 Arc
160 PostScript (ASCII85)
170 PostScript
192 Python
196 JavaScript
199 Common Lisp
212 LilyPond
273 Scheme
280 R
281 sed w/ bc
312 Haskell
314 PHP
339 m4 w/ bc
346 C
381 Fortran
462 Java
718 OCaml
759 F#
1554 sed
C++ not qualified for now
sed in 1554 chars (pure) / 281 (with bc)
Yes, seriously.
Usage: sed -r -f thisfile.sed < input.in > output.out
(works on GNU sed)
1d
/ /!{x
s/^$/Case #Y:/
:i
s/9Y/Y0/
ti
s/#Y/#0Y/
s/:/:0123456789/
s/(.)Y(.*):[0-9]*\1(.).*/\3\2Y:/
x
G
s/.*\n|Y//gp
z
:p
N
/[()]/s/ |\n//g
y/()/JK/
tp
H
d}
G
s/\n[^J]*/ %/
s/[^JK]*$//
:c
s/J1?([.-9]+)(.*)K/\2#\1/
/%#/by
:b
/J/s/T//
s/J([^JK]*)K/TC\1B/
tb
/ (.+) .*%\1C/{s/%[^C]*/%/
s/T.*B//
by}
s/%.*T/%/
:y
y/CB/JK/
tc
s/.\.0*\b//g
:r
/#.*#/{s/\w*#\w*$/C&B/
s/C(\w)(.*B)/\1C\2~/
s/"[^"]*/&0/g
:t
s/(\w)(C.*)(\w)B(.*~)/\1\2B\3\4\1\3/
T
s/~(10|2[01]|3[0-2]|4[0-3]|5[0-4]|6[0-5]|7[0-6]|8[0-7]|9.)/&Q/
s/(.)(.)Q/\2\1/
s/~0\w/`00/
s/~1\B/`0/
s/~22/`04/
s/~23/`06/
s/~24/`08/
s/~33/`09/
s/~25/`10/
s/~26|~34/`12/
s/~27/`14/
s/~28|~44/`16/
s/~29|~36/`18/
s/~35/`15/
s/~45/`20/
s/~37/`21/
s/~38|~46/`24/
s/~55/`25/
s/~39/`27/
s/~47/`28/
s/~56/`30/
s/~48/`32/
s/~57/`35/
s/~49|~66/`36/
s/~58/`40/
s/~67/`42/
s/~59/`45/
s/~68/`48/
s/~77/`49/
s/~69/`54/
s/~78/`56/
s/~79/`63/
s/~88/`64/
s/~89/`72/
s/~99/`81/
s/`(.)(.)/~\1'\2/
bt
:
s/(~.)'/\1/
s/..'/K&/
/K/bk
:v
s/=(,?.)'/\1/
s/,/1'/
t
s/B(.*)~/\1B"/
tr
s/"(\w*)0/A\1/g
/A.*A/{s/A[^A]*$/J&K/
:k
s/([^A])(J.*)([^A])K/\2K\1\3/
s/K(10|2[01]|3[0-2]|4[0-3]|5[0-4]|6[0-5]|7[0-6]|8[^9]|9.)/&Q/
s/(.)(.)Q/\2\1/
s/K0/=/
s/K11/=2/
s/K12/=3/
s/K13|K22/=4/
s/K14|K23/=5/
s/K15|K24|K33/=6/
s/K16|K25|K34/=7/
s/K(17|26|35|44)/=8/
s/K(18|27|36|45)/=9/
s/K(19|28|37|46|55)/W0/
s/K(29|38|47|56)/W1/
s/K(39|48|57|66)/W2/
s/K49|K58|K67/W3/
s/K59|K68|K77/W4/
s/K69|K78/W5/
s/K79|K88/W6/
s/K89/W7/
s/K99/W8/
s/W/=,/
/'/bv
s/\b=/K:/
tk
s/[:JK]A?//g
s/,/,0123456789GF/
s/(.),.*\1(.).*F/\2/
s/G/,0/
tk}
/A.*A/bv}
s/\w*C.*A//
tr
s/.*#/./
This solution omits the leading zero in front of the decimal point, and does not handle cases where the answer is 1.00. Luckily, the GCJ judge accepts the lack of a zero, and does not have any cases where the answer is 1.00.
To include the leading zero, change the last line to s/.*#/0./; and to handle a 1.00 case, append the line s/^$/1/.
Here's a solution that outsources the multiplication to bc:
1d
/ /!{x
s/\n.*//
s/.*/echo 0&+1|bc/e
x
g
s/.*/Case #&:/p
:p
N
/[()]/s/ |\n//g
y/()/JK/
tp
H
d}
G
s/\n[^J]*/ %/
s/[^JK]*$//
:c
s/J([.-9]+)(.*)K/\2*\1/
/%\*/s/.*%.(.*)/echo \1|bc -l/e
:b
/J/s/T//
s/J([^JK]*)K/TC\1B/
tb
/ (.+) .*%\1C/{s/%[^C]*/%/
s/T.*B//
b}
s/%.*T/%/
:
y/CB/JK/
tc
Perl in 107 characters
say("Case #$_:"),
$_=eval"''".'.<>'x<>,
s:[a-z]+:*(/ $&\\s/?:g,s/\)\s*\(/):/g,
eval"\$_=<>;say$_;"x<>for 1..<>
Newlines for legibility; none of them is necessary or counted in.
It uses features found only in the latest versions of Perl, so run with perl -M5.010 or later.
I used to be a Perl noob too, so this works almost the same as the ruby one. Original version 126 chars, optimizations by peutri.
Backlinks:
Word Aligned - Power Programming
LilyPond: 212 characters
Craziness! Utter ridiculousness!! LilyPond, with its built-in Scheme interpreter, manages to outdo Scheme by more than FIFTY BYTES! Holy acrobatic flying mooses in tights!!
x=#lambda
w=#read
#(letrec((v(x(a)(map a(iota(w)1))))(c(x(f q)(*(car q)(if(any list? q)(c
f((if(memq(cadr q)f)caddr cadddr)q))1)))))(v(x(i)(w)(set! #(w))(format
#t"Case #~a:
~{~y~}"i(v(x i(w)(c(v(x i(w)))#)))))))
Usage: lilypond thisfile.ly <input.in >output.out 2>/dev/null
Credit goes to cky for writing the Scheme solution this was based on, though this version is now substantially different. Seriously, though, the Scheme could be golfed a bit further...
PostScript: 170 (regular) / 160 (ASCII85) / 121 (binary)
My shortest (regular) PostScript solution so far, provided that you rename the input file to "r" (170 characters, including newlines); uses a GhostScript-specific procedure (=only):
1[/:{repeat}/!{exch token{\ exch known{/<>}if]pop]]3 index mul
!}if}(]){token pop}/?(r)(r)file([){?]}>>begin
1[{(Case #)2{=only}:(:)=[/|[def[{[/\<<[{[/}:>>def |]! =}:}for
Usage: cp input.in r; gs -q -dNOPROMPT -dNODISPLAY -dBATCH thisfile.ps > output.out
Here's a binary version of this in 121 bytes (backslashes and unprintable characters escaped):
1[/!{\x92>\x92\xab{\\\x92>\x92`\x92p{]\x92u}if]]3\x92X\x92l!}if}(]){\x92\xab\x92u}/r(r)\x928\x92A([){r]}>>\x92\r1[{(Case #)\x92v=only[/:\x928[\x923=[{[/\\<<[{[/}\x92\x83>>\x923:]! =}\x92\x83}\x92H
If characters outside the ASCII printable range are disallowed, PS has built-in ASCII85 encoding of binary sources. We therefore have the following 160-byte solution in all ASCII printable characters:
1[([){r]}/r(r)<~OuSUj0-P\*5*Dsn>`q:6#$5JU?'9>YBkCXV1Qkk'Ca"4#Apl(5.=75YP')1:5*?#0>C.bc#<6!&,:Se!4`>4SH!;p_OuQ[/1Herh>;'5D4Bm/:07B"95!G,c3aEmO4aiKGI?I,~>cvx exec
Ruby in 132
Improved by leonid. Newlines are essential.
def j
'1
'..gets
end
j.map{|c|s=j.map{gets}*''
puts"Case #%d:"%c,j.map{gets;eval s.gsub(/[a-z]+/,'*(/ \&\b/?').gsub /\)\s*\(/,'):'}}
Ruby in 136
def j;1..gets.to_i;end;j.map{|c|m=j.map{gets}*"";puts"Case ##{c}:";j.map{gets;p eval m.gsub(/[a-z]+/,'*(/ \0\s/?').gsub /\)\s*\(/,'):'}}
I just learned about *"" being equivalent to .join"". Also realised that map could be used in a few places
Ruby in 150
1.upto(gets.to_i){|c|m=eval("gets+"*gets.to_i+"''");puts"Case ##{c}:";1.upto(gets.to_i){gets;p eval m.gsub(/[a-z]+/,'*(/ \0\s/?').gsub /\)\s*\(/,'):'}}
I am just a noob to ruby, so there is probably still a lot of room for improvement
Python in 192
import re;S=re.sub;R=raw_input;I=input;c=0;exec r"c+=1;L=S('\) *\(',')or ',S('([a-z]+)','*(\' \\1 \'in a and',eval(('+R()'*I('Case #%s:\n'%c))[1:])));exec'a=R()+\' \';print eval(L);'*I();"*I()
Common Lisp, 199 bytes
Wrapped every 80 characters:
(defun r()(read))(dotimes(i(r))(format t"~&Case #~D:"(1+ i))(r)(set'z(r))(dotime
s(a(r))(r)(print(do((g(mapcar'read(make-list(r))))(p 1(*(pop c)p))(c z(if(find(p
op c)g)(car c)(cadr c))))((not c)p)))))
Spaced and indented:
(defun r () (read))
(dotimes (i (r))
(format t "~&Case #~D:" (1+ i))
(r)
(set 'z (r))
(dotimes (a (r))
(r)
(print
(do ((g (mapcar 'read (make-list (r))))
(p 1 (* (pop c) p))
(c z (if (find (pop c) g)
(car c)
(cadr c))))
((not c) p)))))
C - 346 bytes
Compile with gcc -w
#define N{int n=atoi(gets(A));for(;n--;)
T[999];F[99];char*t,*f,*a,A[99];float p(){float
d,m=1;for(;*t++^40;);sscanf(t,"%f %[^ (]",&d,A);if(*A^41){for(f=F;m**f;){for(;*f&&*f++^32;);for(a=A;*a&&*f==*a;f++,a++);m=*a||*f&64;}d*=!m*p()+m*p();}return
d;}main(I)N{printf("Case #%d:\n",I++);t=T;N
for(gets(t);*++t;);}N gets(F),t=T,printf("%f\n",p());}}}
Arc, 143 154 characters
Very similar to the CL one, but Arc sure has terse identifiers. Wrapped every 40 chars:
(for i 1((= r read))(prn"Case #"i":")(r)
(= z(r))(repeat(r)(r)(loop(= g(n-of(r)(r
))c z p 1)c(= p(*(pop c)p)c(if(pos(pop c
)g)c.0 cadr.c)))prn.p))
Indented:
(for i 1 ((= r read))
(prn "Case #" i ":")
(r)
(= z (r))
(repeat (r)
(r)
(loop (= g (n-of (r) (r))
c z
p 1)
c
(= p (* (pop c) p)
c (if (pos (pop c) g)
(c 0)
(cadr c))))
(prn p)))
Backlink: Word Aligned - Power Programming
JavaScript in 196 bytes
r='replace'
q=readline
for(n=0,t=q();t-n++;){for(print('Case #'+n+':'),d='',x=q();x--;d+=q());for(x=q();x--;)print(eval(d[r](/([a-z]+)/g,'*({'+q()[r](/ /g,':1,z')+':1}.z$1?')[r](/\) *\(/g,'):')))}
Usage: $ smjs thisfile.js <input.in
With contributions by Hyperlisk.
PHP in 314
<?php function q(){return trim(fgets(STDIN));}for($n=q($x=0);$x++<$n;){for($s=q($t='');$s--;$t.=q());echo"Case #$x:\n";for($z=q();$z--;){$l=explode(' ',q());$l[0]=0;printf("%f\n",eval('return'.preg_replace(array('/\(/','/(\w+),/','/(\d\)*),\((\d)/','/^./'),array(',(','*(in_array("$1",$l,1)?','$1:$2'),$t).';'));}}
FORTRAN - 381
Save as a.F95
Compile with f95 a.F95
#define _ ENDDO
#define A READ(t(k:l-1),*),a
#define Q j=1,n;READ"(A)",s
#define R READ*,n;DO
#define S k+SCAN(t(k:),'()')
CHARACTER(999)s,t,u;R i=1,n;t="";PRINT"('Case #'i0':')",i
R Q;t=TRIM(t)//s;_;R Q;d=1;k=1;DO;k=S;l=S-1
IF(t(l:l)>"(")EXIT;A,u;d=d*a;k=l;m=0
IF(INDEX(s," "//TRIM(u)//" ")>0)CYCLE;DO;IF(')'>t(k:k))m=m+2;m=m-1;k=k+1
IF(1>m)EXIT;k=S-1;_;_;A;d=d*a;PRINT*,d;_;_;END
By using the default format, each of the results starts with 2 spaces, but the google judge permits it. Thanks google judge!
EXPANDED VERSION
CHARACTER(999)s,t,u
READ*,n
DO i=1,n
t=""
PRINT"('Case #'I0':')",i
READ*,n
DO j=1,n
READ"(A)",s
t=TRIM(t)//s
ENDDO
READ*,n
DO j=1,n
READ"(A)",s
d=1
k=1
DO
k=k+SCAN(t(k:),'()')
l=k+SCAN(t(k:),'()')-1
IF(t(l:l)>"(")THEN
READ(t(k:l-1),*),a
d=d*a
PRINT*,d
EXIT
ELSE
READ(t(k:l-1),*),a,u
d=d*a
k=l
m=0
IF(INDEX(s," "//TRIM(u)//" ")>0)CYCLE
DO
IF(')'>t(k:k))m=m+2
m=m-1
k=k+1
IF(1>m)EXIT
k=k+SCAN(t(k:),'()')-1
ENDDO
ENDIF
ENDDO
ENDDO
ENDDO
END
Haskell, 312 characters
Here's another aproach to Haskell. I left the dirty work to the Prelude's lex. The wrapping around it is Text.ParserCombinators.ReadP. Importing it cost 36 characters on its own—ugh!
The parser is a Features -> SExp -> Cuteness function, which spares me most of the type declarations in quibble's/yairchu's solution.
import Text.ParserCombinators.ReadP
main=f(\t->do putStrLn$"Case #"++show t++":";s<-r g;r$print.fst.head.($id=<<s).readP_to_S.d.tail.words=<<g)
d x=do"("<-e;w<-e;c<-do{f<-e;y<-d x;n<-d x;u$if elem f x then y else n}<++u 1.0;e;u$c*read w
f x=do n<-g;mapM x[1..read n]
e=readS_to_P lex
r=f.const
g=getLine
u=return
It used to use Control.Monad's join, forM_ and replicateM, but it turns out it takes less space to redefine them approximately than to import.
I also abandoned the Prelude's readParen in favor of just calling lex before and after. In the current version, there is no need to verify the closing parenthesis: on a valid input it will always be there. On the other hand, it is vital to check the opening one: since the number is only converted after the whole subexpression has been read, a lot of backtracking would be needed to align to the correct parse.
On a theoretical machine with infinite memory and time to spare, the "("<- part might be dropped (4 characters' gain, 308 in total). Unless the call to read just aborts. On mine, the stack just overflows pretty fast.
Java in 467 bytes
This uses the javascript interpreter contained in java 6.
import java.util.*;class D{static{Scanner c=new
Scanner(System.in);int n=c.nextInt(),i=0,l;while(i++<n){l=c.nextInt();String
s="(";while(l-->=0)s+=c.nextLine();System.out.println("Case #"+i+":");l=c.nextInt();while(l-->0)try{c.next();System.out.println(new
javax.script.ScriptEngineManager().getEngineByName("js").eval(s.replace(")","))").replaceAll("\\) *\\(",":(").replaceAll("[a-z]+","*(/ $0 /.test('"+c.nextLine()+" ')?")));}catch(Exception
x){}}System.exit(0);}}
Thanks Varan, Chris and pfn (indirectly) for helping me shorten it.
Please see my other (even shorter!) java answer.
m4 with echo and bc, 339 bytes
This solution is a complete and utter hack, and it gives me a headache. It contains, among other things, escaped double quotes, unescaped double quotes, unescapable backquote and single quote pairs (including a nested pair seven quotes deep), unquoted regular expressions, outsourcing decimal multiplication to bc, and the use of craZy caSE to circumvent macro expansion. But it had to be done, I guess. :p
This adds an "ultimate macroizing" solution to the previous kinds of solutions (iterated loops, recursion w/ lambda mapping, labels and branches, regexp and eval, etc.)
I think a good term for this is "macroni code" :D
(wrapped every 60 characters, for clarity)
define(T,`translit($#)')define(Q,`patsubst($#)')define(I,0)Q
(T(T(T(Q(Q(Q(Q(Q(Q(T(include(A),(),<>),>\s*>,>>),>\s*<,>;),\
([a-z]+\)\s*<,`*ifElsE<rEgExp<P;``````` \1 ''''''';0>;0;<'),
^<,`defiNe<````I';iNcr<I>>\\"Case `#'I:\\"defiNe<`A'''';'),^
[0-9]*),.+ [0-9]+.*,`dEfiNE<```P';`\& '''>A'),<>;N,`(),n'),E
,e),()),.*,`syscmd(`echo "\&"|bc -l')')
Usage: $ cp input.in A; m4 thisfile.m4 > output.out
I'm an m4 n00b, though, having learned it only an hour before writing this. So there's probably room for improvement.
C++ in 698 bytes
Compile with 'g++ -o test source.cpp -include iostream -include vector -include sstream'
#define R(x,f,t) for(int x=f;x<t;x++){
#define S(x) x.size()
#define H string
#define U while
#define I if
#define D cin>>
#define X t.substr(p,S(t))
using namespace std;
int main(){int h,l,n,a,p,Y,W;D h;for(int q=1;q<=h;q++){D l;H s;char c;D c;R(i,0,l)H L;getline(cin,L);R(j,0,S(L))I (L[j]==41||L[j]==40)s+=32;s+=L[j];I(L[j]==40)s+=32;}}D a;printf("Case #%d:\n",q);R(i,0,a)H N;D N;D n;vector<H>f;R(j,0,n)D N;f.push_back(N);}H t=s;float P=1;p=0;U(p<S(t)-1){p=0;U(t[p]!=48&&t[p]!=49)p++;t=X;stringstream T(t);float V;T>>V;H F;T>>F;P*=V;I(F[0]==41)break;Y=0;R(j,0,S(f))if(F==f[j])Y=1;}p=t.find(40)+1;t=X;p=0;I(Y==0){W=1;U (W>0){I(t[p]==40)W++;I(t[p]==41)W--;p++;}t=X;p=0;}}cout<<P<<endl;}}return 0;}
EDIT: I'm sorry; I thought it was ok for the includes (eg, C works even w/o including basic libraries), while I'm sure it would be if I decleared the defines this way.
I'm not home now, and I won't be for some time: I won't be able to modify it. Just ignore my submission.
OCaml in 718 bytes
I'm an OCaml n00b, so this is probably much longer than it needs to be.
Usage: ocaml thisfile.ml <input.in >output.out
#load"str.cma";;open List;;open String;;open Str;;let x=length and
y=Printf.printf and e=global_replace and h=float_of_string and b=regexp and
k=index and r=read_line and a=read_int and w s m c=sub s(c+1)(m-c-1);;for i=1to
a()do y"Case #%d:\n"i;let t=let n=a()in let rec g d j=if j>n then d else
g(d^(r()))(j+1)in e(b" ")""(e(b"\\b")"^"(g""1))and n=a()in let rec z j=if j>n
then()else let q=tl(split(b" ")(r()))in let rec g l j s p=let o=k s '('and c=k
s ')'in if j then let f=w s c o in if contains f '('then let m=k s '^'in let
c=index_from s(m+1)'^'in g 0(mem(w s c m)q)(w s(x s)c)(h(w s m o)*.p)else h f*.p
else if o<c then g(l+1)j(w s(x s)o)p else g(l-1)(l=1)(w s(x s)c)p in y"%f\n"(g
0(0=0)t 1.);z(j+1)in z 1done
Scheme (Guile 1.8)
Here's my version at 278 bytes (with improvements from KirarinSnow to bring it down to 273), after stripping off all the newlines (except ones in string literals, of course). It only works on Guile 1.8 (since in standard Scheme, define is a syntax, not an object, but Guile represents it as an object anyway).
(define ! define)
(!(c f p w . r)(if(null? r)(* p w)(apply c f(* p w)((if(memq(car r)f)cadr caddr)r))))
(!(d . l)(map display l))
(!(r . x)(read))
(! n(r))
(do((i 1(1+ i)))((> i n))(r)(let((t(r)))(d"Case #"i":
")(do((a(r)(1- a)))((= a 0))(r)(d(apply c(map r(iota(r)))1 t)"
"))))
Pure java in 440 bytes
A shorter java solution that doesn't use any eval trick. Can be reduced to 425 by removing System.exit(0) if stderr output is ignored.
import java.util.*;enum A{_;Scanner c,d;float p(String a){return
d.nextFloat()*(d.hasNext("\\D+")?a.contains(' '+d.next()+' ')?p(a)+0*p(a):0*p(a)+p(a):1);}{c=new
Scanner(System.in);for(int n=c.nextInt(),i=0,l;i++<n;){String
s="";for(l=c.nextInt();l-->=0;)s+=c.nextLine();System.out.println("Case #"+i+":");for(l=c.nextInt();l-->0;){c.next();d=new
Scanner(s.replaceAll("[()]"," "));System.out.println(p(c.nextLine()+' '));}}System.exit(0);}}
Haskell, 514 bytes (I suck?).
Based on quibble's solution:
import Control.Monad
import Text.ParserCombinators.Parsec
data F=N|F String(Float,F)(Float,F)
r=return
f=many1 letter>>= \i->w>>d>>= \t->d>>=r.F i t
d=char '('>>w>>many1(oneOf".0123456789")>>= \g->w>>(f<|>r N)>>= \p->char ')'>>w>>r(read g,p)
w=many$oneOf" \n"
g=getLine
l=readLn
m=replicateM
main=l>>= \n->forM_[1..n]$ \t->putStrLn("Case #"++show t++":")>>l>>=(`m`g)>>=(\(Right q)->l>>=(`m`p q)).parse d"".join
z(p,f)=(p*).y f
y N _=1
y(F n t f)x=z(if n`elem`x then t else f)x
p q=fmap(drop 2.words)g>>=print.z q
C in 489 bytes
Code wrapped at 80 chars, there are actually just 3 lines.
Save in a.c and compile with: gcc -w a.c -o a
#define S int I,N;scanf("%d\n",&N);for(I=-1;++I<N;)
#define M 1000
char B[M],Z[M],Q[M]={' '},*F[M],*V;float W[M],H;int J,C,L[M],R[M];t(){V=strtok(0
," \n()");}p(){int U=C++;F[U]=0;if(!V)t();sscanf(V,"%f",W+U);t();if(V&&*V>='a')s
trcpy(Q+1,V),V=0,F[U]=strdup(strcat(Q," ")),L[U]=p(),R[U]=p();return U;}main(){S
{printf("Case #%d:\n",I+1);*B=0;{S strcat(B,gets(Z));}V=strtok(B," \n(");C=0,p()
;{S{strcat(gets(B)," ");for(J=0,H=W[0];F[J];J=strstr(B,F[J])?L[J]:R[J],H*=W[J]);
printf("%f\n",H);};}}}
F#: 759 significant chars (Wow, I'm bad at this ;) )
Minimized version
open System.Text.RegularExpressions
type t=T of float*(string*t*t)option
let rec e=function x,T(w,Some(s,a,b))->e(x,if Set.contains s x then a else b)*w|x,T(w,_)->w
let rec h x=Regex.Matches(x, #"\(|\)|\d\.\d+|\S+")|>Seq.cast<Match>|>Seq.map (fun x -> x.Value)|> Seq.toList
let rec p=function ")"::y->p y|"("::w::x::y->match x with ")"->T(float w,None),y|n->let a,f=p y in let b,g=p f in T(float w,Some(n,a,b)),g
let solve input =
Regex.Matches(input,#"(\(((?<s>\()|[^()]|(?<-s>\)))*\)(?(s)(?!)))\s+\d+\s+((\S+\s\d(.+)?\s*)+)")
|>Seq.cast<Match>
|>Seq.map(fun m->fst(p(h(m.Groups.[1].Value))), [for a in m.Groups.[3].Value.Trim().Split([|'\n'|])->set(a.Split([|' '|]))])
|>Seq.iteri(fun i (r,c)->printfn"Case #%i"(i+1);c|>Seq.iter(fun x->printfn"%.7F"(e(x, r))))
Readable version
open System.Text.RegularExpressions
type decisionTree = T of float * (string * decisionTree * decisionTree) option
let rec eval = function
| x, T(w, Some(s, a, b)) -> eval(x, if Set.contains s x then a else b) * w
| x, T(w, _) -> w
// creates a token stream
let rec tokenize tree =
Regex.Matches(tree, #"\(|\)|\d\.\d+|\S+")
|> Seq.cast<Match>
|> Seq.map (fun x -> x.Value)
|> Seq.toList
// converts token stream into a decisionTree
let rec parse = function
| ")"::xs -> parse xs
| "("::weight::x::xs ->
match x with
| ")" -> T(float weight, None), xs
| name ->
let t1, xs' = parse xs
let t2, xs'' = parse xs'
T(float weight, Some(name, t1, t2)), xs''
// uses regex to transform input file into a Seq<decisionTree, list<set<string>>, which each item in our
// list will be tested against the decisionTree
let solve input =
Regex.Matches(input, #"(\(((?<s>\()|[^()]|(?<-s>\)))*\)(?(s)(?!)))\s+\d+\s+((\S+\s\d(.+)?\s*)+)")
|> Seq.cast<Match>
|> Seq.map (fun m -> fst(parse(tokenize(m.Groups.[1].Value))), [for a in m.Groups.[3].Value.Trim().Split([|'\n'|]) -> set(a.Split([|' '|])) ])
|> Seq.iteri (fun i (tree, testCases) ->
printfn "Case #%i" (i+1)
testCases |> Seq.iter (fun testCase -> printfn "%.7F" (eval (testCase, tree)))
)
R in 280 bytes
Note: On the standard distribution of R (as of v. 2.9.2), this program does not pass the large input and fails on just Case 28 (which is nested to 99 levels), generating a "contextstack overflow". To fix this, modify the line in src/main/gram.c that reads
#define CONTEXTSTACK_SIZE 50
and replace the 50 with something like 500. Then recompile. Et voilà!
n=0
g=gsub
eval(parse(text=g('[^
]* [0-9]+( [^
]*|
)','f=c(\\1)
cat(eval(d),"
")
',g('
\\(','
cat("Case #",n<-n+1,":
",sep="")
d=expression(',g('" "','","',g(')\\s*\\(',',',g(' *("[a-z]+")\\s*\\(','*ifelse(\\1%in%f,',g('([a-z]+)','"\\1"',paste(readLines('A'),collapse='
')))))))))
Usage (requires renaming input): cp input.in A; R -q --slave -f thisfile.R >output.out