First class environments: Difference between revisions
m (→{{header|Tcl}}: Fix partial line (d'oh!)) |
m (<lang> needs a language) |
||
Line 19: | Line 19: | ||
=={{header|C}}== |
=={{header|C}}== |
||
Well, this fits the semantics, not sure about the |
Well, this fits the semantics, not sure about the spirit… |
||
<lang C>#include <stdio.h> |
|||
#define JOBS 12 |
#define JOBS 12 |
||
Line 54: | Line 55: | ||
return 0; |
return 0; |
||
}</ |
}</lang> |
||
{{out}} |
|||
<pre> |
|||
1 2 3 4 5 6 7 8 9 10 11 12 |
1 2 3 4 5 6 7 8 9 10 11 12 |
||
1 1 10 2 16 3 22 4 28 5 34 6 |
1 1 10 2 16 3 22 4 28 5 34 6 |
||
Line 76: | Line 79: | ||
COUNTS: |
COUNTS: |
||
0 1 7 2 5 8 16 3 19 6 14 9 |
0 1 7 2 5 8 16 3 19 6 14 9 |
||
</pre> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
{{incorrect|Go|The libraries have changed and this example no longer works.}} |
{{incorrect|Go|The libraries have changed and this example no longer works.}} |
||
Line 194: | Line 199: | ||
*v = intV(o.(eval.IntValue).Get(t)) |
*v = intV(o.(eval.IntValue).Get(t)) |
||
}</lang> |
}</lang> |
||
{{out}} |
|||
Output: |
|||
<pre> |
<pre> |
||
1 2 3 4 5 6 7 8 9 10 11 12 |
1 2 3 4 5 6 7 8 9 10 11 12 |
||
Line 245: | Line 250: | ||
} |
} |
||
end</lang> |
end</lang> |
||
{{libheader|Icon Programming Library}} |
{{libheader|Icon Programming Library}} |
||
[http://www.cs.arizona.edu/icon/library/src/procs/printf.icn printf.icn provides formatting] |
[http://www.cs.arizona.edu/icon/library/src/procs/printf.icn printf.icn provides formatting] |
||
{{out}} |
|||
<pre>Sequences: |
|||
1 2 3 4 5 6 7 8 9 10 11 12 |
1 2 3 4 5 6 7 8 9 10 11 12 |
||
1 1 10 2 16 3 22 4 28 5 34 6 |
1 1 10 2 16 3 22 4 28 5 34 6 |
||
Line 274: | Line 278: | ||
=={{header|J}}== |
=={{header|J}}== |
||
I have tried to determine what makes this task interesting (see talk page), but I am still confused. |
I have tried to determine what makes this task interesting (see talk page), but I am still confused. |
||
Here is my current interpretation of the task requirements: |
Here is my current interpretation of the task requirements: |
||
<lang j>coclass 'hailstone' |
<lang j>coclass 'hailstone' |
||
Line 314: | Line 316: | ||
end. |
end. |
||
)</lang> |
)</lang> |
||
⚫ | |||
⚫ | |||
<lang j> environments=: conew&'hailstone'"0 (1+i.12) |
<lang j> environments=: conew&'hailstone'"0 (1+i.12) |
||
run_hailstone_ environments |
run_hailstone_ environments |
||
Line 339: | Line 339: | ||
1 1 1 1 1 1 1 1 1 1 1 1 |
1 1 1 1 1 1 1 1 1 1 1 1 |
||
0 1 7 2 5 8 16 3 19 6 14 9</lang> |
0 1 7 2 5 8 16 3 19 6 14 9</lang> |
||
In essence: run is a static method of the class <code>hailstone</code> which, given a list of objects of the class runs all of them until their hailstone sequence number stops changing. It also displays the hailstone sequence number from each of the objects at each step. Its result is the step count from each object. |
In essence: run is a static method of the class <code>hailstone</code> which, given a list of objects of the class runs all of them until their hailstone sequence number stops changing. It also displays the hailstone sequence number from each of the objects at each step. Its result is the step count from each object. |
||
Line 364: | Line 363: | ||
(prin (align 4 Cnt)) ) ) # print the step count |
(prin (align 4 Cnt)) ) ) # print the step count |
||
(prinl) )</lang> |
(prinl) )</lang> |
||
{{out}} |
|||
Output: |
|||
<pre> 1 2 3 4 5 6 7 8 9 10 11 12 |
<pre> 1 2 3 4 5 6 7 8 9 10 11 12 |
||
1 1 10 2 16 3 22 4 28 5 34 6 |
1 1 10 2 16 3 22 4 28 5 34 6 |
||
Line 407: | Line 406: | ||
print('% 4d' % env['cnt'], end='') |
print('% 4d' % env['cnt'], end='') |
||
print()</lang> |
print()</lang> |
||
{{out}} |
|||
;Output: |
|||
<pre> 1 2 3 4 5 6 7 8 9 10 11 12 |
<pre> 1 2 3 4 5 6 7 8 9 10 11 12 |
||
1 1 10 2 16 3 22 4 28 5 34 6 |
1 1 10 2 16 3 22 4 28 5 34 6 |
||
Line 434: | Line 432: | ||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
{{trans|PicoLisp}} |
{{trans|PicoLisp}} |
||
The ''object'' is an environment for instance variables. These variables use the <code>@</code> sigil. We create 12 objects, and put <code>@n</code> and <code>@cnt</code> inside these objects. We use <code>Object#instance_eval</code> to switch the current object and bring those instance variables into scope. |
The ''object'' is an environment for instance variables. These variables use the <code>@</code> sigil. We create 12 objects, and put <code>@n</code> and <code>@cnt</code> inside these objects. We use <code>Object#instance_eval</code> to switch the current object and bring those instance variables into scope. |
||
<lang ruby># Build environments |
<lang ruby># Build environments |
||
envs = (1..12).map do |n| |
envs = (1..12).map do |n| |
||
Line 466: | Line 462: | ||
end |
end |
||
puts</lang> |
puts</lang> |
||
---- |
|||
Ruby also provides the ''binding'', an environment for local variables. The problem is that local variables have lexical scope. Ruby needs the lexical scope to parse Ruby code. So, the only way to use a binding is to evaluate a string of Ruby code. We use <code>Kernel#binding</code> to create the bindings, and <code>Kernel#eval</code> to evaluate strings in these bindings. The lines between <code><<-'eos'</code> and <code>eos</code> are multi-line string literals. |
Ruby also provides the ''binding'', an environment for local variables. The problem is that local variables have lexical scope. Ruby needs the lexical scope to parse Ruby code. So, the only way to use a binding is to evaluate a string of Ruby code. We use <code>Kernel#binding</code> to create the bindings, and <code>Kernel#eval</code> to evaluate strings in these bindings. The lines between <code><<-'eos'</code> and <code>eos</code> are multi-line string literals. |
||
<lang ruby># Build environments |
<lang ruby># Build environments |
||
envs = (1..12).map do |n| |
envs = (1..12).map do |n| |
||
Line 543: | Line 535: | ||
} |
} |
||
puts ""</lang> |
puts ""</lang> |
||
{{out}} |
|||
Output: |
|||
<pre> |
<pre> |
||
1 2 3 4 5 6 7 8 9 10 11 12 |
1 2 3 4 5 6 7 8 9 10 11 12 |
Revision as of 07:42, 25 February 2012
You are encouraged to solve this task according to the task description, using any language you may know.
According to Wikipedia, "In computing, a first-class object ... is an entity that can be constructed at run-time, passed as a parameter, returned from a subroutine, or assigned into a variable".
Often this term is used in the context of "first class functions". In an analogous way, a programming language may support "first class environments".
The environment is minimally, the set of variables accessable to a statement being executed. Change the environments and the same statement could produce different results when executed.
Often an environment is captured in a closure, which encapsulates a function together with an environment. That environment, however, is not first-class, as it cannot be created, passed etc. independently from the function's code.
Therefore, a first class environment is a set of variable bindings which can be constructed at run-time, passed as a parameter, returned from a subroutine, or assigned into a variable. It is like a closure without code. A statement must be able to be executed within a stored first class environment and act according to the environment variable values stored within.
The task: Build a dozen environments, and a single piece of code to be run repeatedly in each of these envionments.
Each environment contains the bindings for two variables: A value in the Hailstone sequence, and a count which is incremented until the value drops to 1. The initial hailstone values are 1 through 12, and the count in each environment is zero.
When the code runs, it calculates the next hailstone step in the current environment (unless the value is already 1) and counts the steps. Then it prints the current value in a tabular form.
When all hailstone values dropped to 1, processing stops, and the total number of hailstone steps for each environment is printed.
C
Well, this fits the semantics, not sure about the spirit… <lang C>#include <stdio.h>
- define JOBS 12
- define jobs(a) for (switch_to(a = 0); a < JOBS || !printf("\n"); switch_to(++a))
typedef struct { int seq, cnt; } env_t;
env_t env[JOBS] = Template:0, 0; int *seq, *cnt;
void hail() { printf("% 4d", *seq); if (*seq == 1) return; ++*cnt; *seq = (*seq & 1) ? 3 * *seq + 1 : *seq / 2; }
void switch_to(int id) { seq = &env[id].seq; cnt = &env[id].cnt; }
int main() { int i; jobs(i) { env[i].seq = i + 1; }
again: jobs(i) { hail(); } jobs(i) { if (1 != *seq) goto again; }
printf("COUNTS:\n"); jobs(i) { printf("% 4d", *cnt); }
return 0; }</lang>
- Output:
1 2 3 4 5 6 7 8 9 10 11 12 1 1 10 2 16 3 22 4 28 5 34 6 1 1 5 1 8 10 11 2 14 16 17 3 1 1 16 1 4 5 34 1 7 8 52 10 1 1 8 1 2 16 17 1 22 4 26 5 1 1 4 1 1 8 52 1 11 2 13 16 1 1 2 1 1 4 26 1 34 1 40 8 1 1 1 1 1 2 13 1 17 1 20 4 1 1 1 1 1 1 40 1 52 1 10 2 1 1 1 1 1 1 20 1 26 1 5 1 1 1 1 1 1 1 10 1 13 1 16 1 1 1 1 1 1 1 5 1 40 1 8 1 1 1 1 1 1 1 16 1 20 1 4 1 1 1 1 1 1 1 8 1 10 1 2 1 1 1 1 1 1 1 4 1 5 1 1 1 1 1 1 1 1 1 2 1 16 1 1 1 1 1 1 1 1 1 1 1 8 1 1 1 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 COUNTS: 0 1 7 2 5 8 16 3 19 6 14 9
Go
Using eval package originally part of Go standard library, now externally hosted and maintained.
Variance: package support is yet incomplete, so the common piece of code has no way to print hv, as requested by the task. Instead, printing is done outside of the common piece of code, by directly inspecting the environments. <lang go>package main
import (
"bitbucket.org/binet/go-eval/pkg/eval" "fmt" "go/parser" "go/token"
)
type pair struct {
name string value int
}
type environment struct {
binding map[string]*intV world *eval.World
}
func newEnvironment(iv []pair) (environment, error) {
e := environment{make(map[string]*intV), eval.NewWorld()} for _, p := range iv { v := intV(p.value) err := e.world.DefineVar(p.name, eval.IntType, &v) if err != nil { return environment{}, err } e.binding[p.name] = &v } return e, nil
}
func main() {
// create 12 environments with intial values e12 := make([]environment, 12) var err error for i := range e12 { e12[i], err = newEnvironment([]pair{{"hv", i + 1}, {"count", 0}}) if err != nil { fmt.Println(err) return } } // define single piece of code. // the parser returns a list of abstract syntax trees. fset := token.NewFileSet() spoc, err := parser.ParseStmtList(fset, "spoc", ` if hv > 1 { if hv % 2 == 0 { hv /= 2 } else { hv = 3*hv + 1 } count++ } `) if err != nil { fmt.Println(err) return } // iterate until all sequences complete
all:
for { // check for all sequences complete for i := 0; *e12[i].binding["hv"] == 1; i++ { if i == 11 { break all } } // iterate sequences for _, e := range e12 { // output hv in this environment // (library deficiency that it can't be done in the spoc.) fmt.Printf(" %3d", *e.binding["hv"])
// bind code, code, err := e.world.CompileStmtList(fset, spoc) if err != nil { fmt.Println(err) return } // evaluate, _, err = code.Run() if err != nil { fmt.Println(err) return } // and abandon the code binding. it's a little wasteful. // code binding could be done up front, once for each environment, // and saved in the environment struct. it's repeated here just // to avoid the question of whether it is still a "single piece // of code" if it is compiled 12 times and pointers to the 12 // instances are saved. } fmt.Println() } fmt.Println("Counts:") for _, e := range e12 { fmt.Printf(" %3d", *e.binding["count"]) } fmt.Println()
}
// int value implementation type intV int
func (v *intV) String() string { return fmt.Sprint(*v) } func (v *intV) Get(*eval.Thread) int64 { return int64(*v) } func (v *intV) Set(_ *eval.Thread, x int64) { *v = intV(x) } func (v *intV) Assign(t *eval.Thread, o eval.Value) {
*v = intV(o.(eval.IntValue).Get(t))
}</lang>
- Output:
1 2 3 4 5 6 7 8 9 10 11 12 1 1 10 2 16 3 22 4 28 5 34 6 1 1 5 1 8 10 11 2 14 16 17 3 1 1 16 1 4 5 34 1 7 8 52 10 1 1 8 1 2 16 17 1 22 4 26 5 1 1 4 1 1 8 52 1 11 2 13 16 1 1 2 1 1 4 26 1 34 1 40 8 1 1 1 1 1 2 13 1 17 1 20 4 1 1 1 1 1 1 40 1 52 1 10 2 1 1 1 1 1 1 20 1 26 1 5 1 1 1 1 1 1 1 10 1 13 1 16 1 1 1 1 1 1 1 5 1 40 1 8 1 1 1 1 1 1 1 16 1 20 1 4 1 1 1 1 1 1 1 8 1 10 1 2 1 1 1 1 1 1 1 4 1 5 1 1 1 1 1 1 1 1 1 2 1 16 1 1 1 1 1 1 1 1 1 1 1 8 1 1 1 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 Counts: 0 1 7 2 5 8 16 3 19 6 14 9
Icon and Unicon
The simplest way to create an environment with variables isolated from code in Icon/Unicon is to create instances of records or class objects. <lang Icon>link printf
procedure main()
every put(environment := [], hailenv(1 to 12,0)) # setup environments printf("Sequences:\n") while (e := !environment).sequence > 1 do { every hailstep(!environment) printf("\n") } printf("\nCounts:\n") every printf("%4d ",(!environment).count) printf("\n")
end
record hailenv(sequence,count)
procedure hailstep(env)
printf("%4d ",env.sequence) if env.sequence ~= 1 then { env.count +:= 1 if env.sequence % 2 = 0 then env.sequence /:= 2 else env.sequence := 3 * env.sequence + 1 }
end</lang>
printf.icn provides formatting
- Output:
Sequences: 1 2 3 4 5 6 7 8 9 10 11 12 1 1 10 2 16 3 22 4 28 5 34 6 1 1 5 1 8 10 11 2 14 16 17 3 1 1 16 1 4 5 34 1 7 8 52 10 1 1 8 1 2 16 17 1 22 4 26 5 1 1 4 1 1 8 52 1 11 2 13 16 1 1 2 1 1 4 26 1 34 1 40 8 1 1 1 1 1 2 13 1 17 1 20 4 1 1 1 1 1 1 40 1 52 1 10 2 1 1 1 1 1 1 20 1 26 1 5 1 1 1 1 1 1 1 10 1 13 1 16 1 1 1 1 1 1 1 5 1 40 1 8 1 1 1 1 1 1 1 16 1 20 1 4 1 1 1 1 1 1 1 8 1 10 1 2 1 1 1 1 1 1 1 4 1 5 1 1 1 1 1 1 1 1 1 2 1 16 1 1 1 1 1 1 1 1 1 1 1 8 1 1 1 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 Counts: 0 1 7 2 5 8 16 3 19 6 14 9
J
I have tried to determine what makes this task interesting (see talk page), but I am still confused.
Here is my current interpretation of the task requirements: <lang j>coclass 'hailstone'
step=:3 :0
NB. and determine next element in hailstone sequence if.1=N do. N return.end. NB. count how many times this has run when N was not 1 STEP=:STEP+1 if.0=2|N do. N=: N%2 else. N=: 1 + 3*N end.
)
create=:3 :0
STEP=: 0 N=: y
)
current=:3 :0
N__y
)
run1=:3 :0
step__y STEP__y
)
run=:3 :0
old=: while. -. old -: state=: run1"0 y do. smoutput 4j0 ": current"0 y old=: state end.
)</lang>
- Example use:
<lang j> environments=: conew&'hailstone'"0 (1+i.12)
run_hailstone_ environments 1 1 10 2 16 3 22 4 28 5 34 6 1 1 5 1 8 10 11 2 14 16 17 3 1 1 16 1 4 5 34 1 7 8 52 10 1 1 8 1 2 16 17 1 22 4 26 5 1 1 4 1 1 8 52 1 11 2 13 16 1 1 2 1 1 4 26 1 34 1 40 8 1 1 1 1 1 2 13 1 17 1 20 4 1 1 1 1 1 1 40 1 52 1 10 2 1 1 1 1 1 1 20 1 26 1 5 1 1 1 1 1 1 1 10 1 13 1 16 1 1 1 1 1 1 1 5 1 40 1 8 1 1 1 1 1 1 1 16 1 20 1 4 1 1 1 1 1 1 1 8 1 10 1 2 1 1 1 1 1 1 1 4 1 5 1 1 1 1 1 1 1 1 1 2 1 16 1 1 1 1 1 1 1 1 1 1 1 8 1 1 1 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 1 7 2 5 8 16 3 19 6 14 9</lang>
In essence: run is a static method of the class hailstone
which, given a list of objects of the class runs all of them until their hailstone sequence number stops changing. It also displays the hailstone sequence number from each of the objects at each step. Its result is the step count from each object.
PicoLisp
Runtime environments can be controlled with the 'job' function: <lang PicoLisp>(let Envs
(mapcar '((N) (list (cons 'N N) (cons 'Cnt 0))) # Build environments (range 1 12) ) (while (find '((E) (job E (> N 1))) Envs) # Until all values are 1: (for E Envs (job E # Use environment 'E' (prin (align 4 N)) (unless (= 1 N) (inc 'Cnt) # Increment step count (setq N (if (bit? 1 N) # Calculate next hailstone value (inc (* N 3)) (/ N 2) ) ) ) ) ) (prinl) ) (prinl (need 48 '=)) (for E Envs # For each environment 'E' (job E (prin (align 4 Cnt)) ) ) # print the step count (prinl) )</lang>
- Output:
1 2 3 4 5 6 7 8 9 10 11 12 1 1 10 2 16 3 22 4 28 5 34 6 1 1 5 1 8 10 11 2 14 16 17 3 1 1 16 1 4 5 34 1 7 8 52 10 1 1 8 1 2 16 17 1 22 4 26 5 1 1 4 1 1 8 52 1 11 2 13 16 1 1 2 1 1 4 26 1 34 1 40 8 1 1 1 1 1 2 13 1 17 1 20 4 1 1 1 1 1 1 40 1 52 1 10 2 1 1 1 1 1 1 20 1 26 1 5 1 1 1 1 1 1 1 10 1 13 1 16 1 1 1 1 1 1 1 5 1 40 1 8 1 1 1 1 1 1 1 16 1 20 1 4 1 1 1 1 1 1 1 8 1 10 1 2 1 1 1 1 1 1 1 4 1 5 1 1 1 1 1 1 1 1 1 2 1 16 1 1 1 1 1 1 1 1 1 1 1 8 1 1 1 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 ================================================ 0 1 7 2 5 8 16 3 19 6 14 9
Python
In Python, name bindings are held in dicts, one for global scope and another for local scope. When exec'ing code, you are allowed to give your own dictionaries for these scopes. In this example, two names are held in dictionaries that are used as the local scope for the evaluation of source. <lang python>environments = [{'cnt':0, 'seq':i+1} for i in range(12)]
code = print('% 4d' % seq, end=) if seq != 1:
cnt += 1 seq = 3 * seq + 1 if seq & 1 else seq // 2
while any(env['seq'] > 1 for env in environments):
for env in environments: exec(code, globals(), env) print()
print('Counts') for env in environments:
print('% 4d' % env['cnt'], end=)
print()</lang>
- Output:
1 2 3 4 5 6 7 8 9 10 11 12 1 1 10 2 16 3 22 4 28 5 34 6 1 1 5 1 8 10 11 2 14 16 17 3 1 1 16 1 4 5 34 1 7 8 52 10 1 1 8 1 2 16 17 1 22 4 26 5 1 1 4 1 1 8 52 1 11 2 13 16 1 1 2 1 1 4 26 1 34 1 40 8 1 1 1 1 1 2 13 1 17 1 20 4 1 1 1 1 1 1 40 1 52 1 10 2 1 1 1 1 1 1 20 1 26 1 5 1 1 1 1 1 1 1 10 1 13 1 16 1 1 1 1 1 1 1 5 1 40 1 8 1 1 1 1 1 1 1 16 1 20 1 4 1 1 1 1 1 1 1 8 1 10 1 2 1 1 1 1 1 1 1 4 1 5 1 1 1 1 1 1 1 1 1 2 1 16 1 1 1 1 1 1 1 1 1 1 1 8 1 1 1 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 Counts 0 1 7 2 5 8 16 3 19 6 14 9
Ruby
The object is an environment for instance variables. These variables use the @
sigil. We create 12 objects, and put @n
and @cnt
inside these objects. We use Object#instance_eval
to switch the current object and bring those instance variables into scope.
<lang ruby># Build environments
envs = (1..12).map do |n|
Object.new.instance_eval {@n = n; @cnt = 0; self}
end
- Until all values are 1:
while envs.find {|e| e.instance_eval {@n} > 1}
envs.each do |e| e.instance_eval do # Use environment _e_ printf "%4s", @n unless 1 == @n @cnt += 1 # Increment step count @n = if 1 & @n == 1 # Calculate next hailstone value @n * 3 + 1 else @n / 2 end end end end puts
end puts '=' * 48 envs.each do |e| # For each environment _e_
e.instance_eval do printf "%4s", @cnt # print the step count end
end
puts</lang>
Ruby also provides the binding, an environment for local variables. The problem is that local variables have lexical scope. Ruby needs the lexical scope to parse Ruby code. So, the only way to use a binding is to evaluate a string of Ruby code. We use Kernel#binding
to create the bindings, and Kernel#eval
to evaluate strings in these bindings. The lines between <<-'eos'
and eos
are multi-line string literals.
<lang ruby># Build environments
envs = (1..12).map do |n|
e = class Object # This is a new lexical scope with no local variables. # Create a new binding here. binding end eval(<<-'eos', e).call(n) n, cnt = nil, 0 proc {|arg| n = arg} eos next e
end
- Until all values are 1:
while envs.find {|e| eval('n > 1', e)}
envs.each do |e| eval(<<-'eos', e) # Use environment _e_ printf "%4s", n unless 1 == n cnt += 1 # Increment step count n = if 1 & n == 1 # Calculate next hailstone value n * 3 + 1 else n / 2 end end eos end puts
end puts '=' * 48 envs.each do |e| # For each environment _e_
eval(<<-'eos', e) printf "%4s", cnt # print the step count eos
end puts</lang>
Tcl
The simplest way to make a first-class environment in Tcl is to use a dictionary; the dict with
command (and dict update
; not shown here) will expand a dictionary and bind it to variables for the duration of its body script.
<lang tcl>package require Tcl 8.5
for {set i 1} {$i <= 12} {incr i} {
dict set hailenv hail$i [dict create num $i steps 0]
} while 1 {
set loopagain false foreach k [dict keys $hailenv] {
dict with hailenv $k { puts -nonewline [format %4d $num] if {$num == 1} { continue } elseif {$num & 1} { set num [expr {3*$num + 1}] } else { set num [expr {$num / 2}] } set loopagain true incr steps }
} puts "" if {!$loopagain} break
} puts "Counts..." foreach k [dict keys $hailenv] {
dict with hailenv $k {
puts -nonewline [format %4d $steps]
}
} puts ""</lang>
- Output:
1 2 3 4 5 6 7 8 9 10 11 12 1 1 10 2 16 3 22 4 28 5 34 6 1 1 5 1 8 10 11 2 14 16 17 3 1 1 16 1 4 5 34 1 7 8 52 10 1 1 8 1 2 16 17 1 22 4 26 5 1 1 4 1 1 8 52 1 11 2 13 16 1 1 2 1 1 4 26 1 34 1 40 8 1 1 1 1 1 2 13 1 17 1 20 4 1 1 1 1 1 1 40 1 52 1 10 2 1 1 1 1 1 1 20 1 26 1 5 1 1 1 1 1 1 1 10 1 13 1 16 1 1 1 1 1 1 1 5 1 40 1 8 1 1 1 1 1 1 1 16 1 20 1 4 1 1 1 1 1 1 1 8 1 10 1 2 1 1 1 1 1 1 1 4 1 5 1 1 1 1 1 1 1 1 1 2 1 16 1 1 1 1 1 1 1 1 1 1 1 8 1 1 1 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 Counts... 0 1 7 2 5 8 16 3 19 6 14 9