Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #28348 > unrolled thread
| Started by | Julian Fondren <julian.fondren@gmail.com> |
|---|---|
| First post | 2014-02-12 17:37 -0800 |
| Last post | 2014-02-13 20:23 -0800 |
| Articles | 20 on this page of 21 — 9 participants |
Back to article view | Back to comp.lang.forth
Rosetta Code: Top rank per group Julian Fondren <julian.fondren@gmail.com> - 2014-02-12 17:37 -0800
Re: Rosetta Code: Top rank per group "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2014-02-13 03:58 -0500
Re: Rosetta Code: Top rank per group Hans Bezemer <the.beez.speaks@gmail.com> - 2014-02-13 19:11 +0100
Re: Rosetta Code: Top rank per group Julian Fondren <julian.fondren@gmail.com> - 2014-02-13 12:08 -0800
Re: Rosetta Code: Top rank per group Hans Bezemer <the.beez.speaks@gmail.com> - 2014-02-14 10:57 +0100
Re: Rosetta Code: Top rank per group Paul Rubin <no.email@nospam.invalid> - 2014-02-14 02:50 -0800
Jensen's device (was: Rosetta Code: ...) anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2014-02-14 11:48 +0000
Re: Jensen's device (was: Rosetta Code: ...) Hans Bezemer <the.beez.speaks@gmail.com> - 2014-02-14 16:46 +0100
Re: Jensen's device (was: Rosetta Code: ...) "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2014-02-14 11:30 -0500
Re: Jensen's device (was: Rosetta Code: ...) Hans Bezemer <the.beez.speaks@gmail.com> - 2014-02-14 23:35 +0100
Re: Jensen's device (was: Rosetta Code: ...) anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2014-02-15 13:36 +0000
Re: Jensen's device (was: Rosetta Code: ...) albert@spenarnc.xs4all.nl (Albert van der Horst) - 2014-02-14 19:12 +0000
Re: Jensen's device (was: Rosetta Code: ...) mhx@iae.nl - 2014-02-14 12:13 -0800
Re: Jensen's device (was: Rosetta Code: ...) Hans Bezemer <the.beez.speaks@gmail.com> - 2014-02-14 23:47 +0100
Re: Jensen's device (was: Rosetta Code: ...) mhx@iae.nl - 2014-02-14 23:45 -0800
Re: Jensen's device (was: Rosetta Code: ...) mhx@iae.nl - 2014-02-15 02:49 -0800
Re: Jensen's device (was: Rosetta Code: ...) albert@spenarnc.xs4all.nl (Albert van der Horst) - 2014-02-15 11:54 +0000
Re: Rosetta Code: Top rank per group Hans Bezemer <the.beez.speaks@gmail.com> - 2014-02-13 23:20 +0100
Re: Rosetta Code: Top rank per group Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-02-13 04:11 -0600
Re: Rosetta Code: Top rank per group humptydumpty <ouatubi@gmail.com> - 2014-02-13 10:48 -0800
Re: Rosetta Code: Top rank per group humptydumpty <ouatubi@gmail.com> - 2014-02-13 20:23 -0800
Page 1 of 2 [1] 2 Next page →
| From | Julian Fondren <julian.fondren@gmail.com> |
|---|---|
| Date | 2014-02-12 17:37 -0800 |
| Subject | Rosetta Code: Top rank per group |
| Message-ID | <77e31dd1-7692-4ef6-83b7-8f2fe3cb7957@googlegroups.com> |
Hello clf,
Rosetta Code has a 'top rank per group' task:
http://rosettacode.org/wiki/Top_rank_per_group
Which reads:
---
Find the top N salaries in each department, where N is provided as a parameter.
Use this data as a formatted internal data structure (adapt it to your
language-native idioms, rather than parse at runtime), or identify your
external data source:
Employee Name,Employee ID,Salary,Department
Tyler Bennett,E10297,32000,D101
John Rappl,E21437,47000,D050
George Woltman,E00127,53500,D101
Adam Smith,E63535,18000,D202
Claire Buckman,E39876,27800,D202
David McClellan,E04242,41500,D101
Rich Holcomb,E01234,49500,D202
Nathan Adams,E41298,21900,D050
Richard Potter,E43128,15900,D101
David Motsinger,E27002,19250,D202
Tim Sampair,E03033,27000,D101
Kim Arlich,E10001,57000,D190
Timothy Grove,E16398,29900,D190
---
If you look on the page you'll note that there is no Forth solution.
In general, I think there are three good kinds of solutions to this problem,
with the best depending on your circumstances. They are:
1. brute-force the answer with high-level data structures: walk the table,
adding departments as keys to a hash table, the values of which are lists of
salaries. Once you've exhausted the table, sort the keys of the hash (for nice
output) and then print them and their top N of the sorted lists of salaries.
(If you've never used a Perl oneliner that you wrote in a minute to chew on
multiple repquota streams and spit out the top diskspace-using users, then that
I call this a 'good solution' may puzzle you.)
2. feed this table to a relational DBMS and then use SQL to get the answer.
3. partially reinvent relational databases. Even if the most advanced text
that you've read is The Manga Guide to Databases, it'll immediately strike you
that the table above may look nice, but... if you split it up and rearrange it
a bit *like so*, it can be much easier to work with...
There is also, no pun intended and nothing meant by it, a fourth solution:
solve the problem with custom data types and algorithms that are closely
dependent on both the exact query and the exact data.
I'd like to demonstrate a solution of this last kind.
First, an uninteresting representation of the employee table: a solid mass of
counted strings.
: string, ( c-addr u -- )
dup c, here swap dup allot move ;
variable #employees
: | ( -- )
1 #employees +!
begin [char] , parse dup while string, repeat 2drop ;
create employees
\ Employee Name,Employee ID,Salary,Department
| Tyler Bennett,E10297,32000,D101
| John Rappl,E21437,47000,D050
| George Woltman,E00127,53500,D101
| Adam Smith,E63535,18000,D202
| Claire Buckman,E39876,27800,D202
| David McClellan,E04242,41500,D101
| Rich Holcomb,E01234,49500,D202
| Nathan Adams,E41298,21900,D050
| Richard Potter,E43128,15900,D101
| David Motsinger,E27002,19250,D202
| Tim Sampair,E03033,27000,D101
| Kim Arlich,E10001,57000,D190
| Timothy Grove,E16398,29900,D190
4 constant #columns
: .employee ( a -- )
cr #columns 1 do count 2dup type ." , " + loop count type ;
: /employee ( a -- a' )
#columns 0 do count + loop ;
: salary ( a -- n )
count + count + count 0. 2swap >number 2drop d>s ;
: department ( a -- n )
count + count + count + count 0. 2swap 1 /string >NUMBER 2drop d>s ;
: .employees ( -- )
employees #employees @ 0 do dup .employee /employee loop drop ;
Second, an always-sorted 'top N' type:
( top-N array : {max,cur,x*cur} )
: topn ( n -- a )
dup 2 + cells dup allocate throw tuck swap erase
tuck ! 0 over cell+ ! ;
: >topn ( n a -- )
dup 2@ <> if 1 over cell+ +! then
dup 2 cells + swap cell+ @ cells bounds do
dup i @ > if i @ swap i ! then
cell +loop drop ;
: .topn ( a -- )
cell+ dup cell+ swap @ cells bounds ?do i @ . cell +loop ;
Third, since the departments are numerical and with a small range, and again so
that I don't have to *sort* anything, an array of potential departments with
their values either 0 or a TOPN, and then the final words.
( query )
variable max-n
300 constant #departments
create departments #departments cells allot
: >department ( n-salary n-department -- )
cells departments + dup @ if @ >topn
else max-n @ topn tuck swap ! >topn then ;
: query ( -- ) \ top N salaries by department
departments #departments cells erase
employees #employees @ 0 do
dup salary over department >department
/employee loop drop ;
: .top-salaries ( -- )
#departments 0 do
i cells departments + @
dup if cr ." D" i 0 .r space .topn else drop
then loop ;
: top-salaries ( n -- )
max-n ! query .top-salaries ;
And that's it. No questions about any of that? OK. With user input indented and with extra spacing:
3 top-salaries
D50 47000 21900
D101 53500 41500 32000
D190 57000 29900
D202 49500 27800 19250 ok
1 top-salaries
D50 47000
D101 53500
D190 57000
D202 49500 ok
400 top-salaries
D50 47000 21900
D101 53500 41500 32000 27000 15900
D190 57000 29900
D202 49500 27800 19250 18000 ok
Although the query is 'top *salaries* by department', now that I look at the
other answers on that page, I see that every one of them provides the employee
record associated with the top salaries. For that, TOPN could have pairs of
(salary,employee record address) cells.
I haven't submitted this as an answer to the 'Top rank per group' task on
Rosetta Code; I'm more tempted to provide a brute-force-with-high-level-data-structures answer. I'd like to see how you would answer this task.
-- Julian
[toc] | [next] | [standalone]
| From | "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> |
|---|---|
| Date | 2014-02-13 03:58 -0500 |
| Message-ID | <op.xa7pvk0u5zc71u@localhost> |
| In reply to | #28348 |
On Wed, 12 Feb 2014 20:37:15 -0500, Julian Fondren <julian.fondren@gmail.com> wrote: > Rosetta Code has a 'top rank per group' task: > http://rosettacode.org/wiki/Top_rank_per_group > > [snip] Forth examples are not available for many of the Rosetta Code tasks. Why is this one of interest to you? Most notably, Forth is not even on the *metaprogramming* page: http://rosettacode.org/wiki/Metaprogramming Sad... It's not on many, many others too: http://rosettacode.org/wiki/Parsing/RPN_to_infix_conversion http://rosettacode.org/wiki/Create_an_HTML_table http://rosettacode.org/wiki/ABC_Problem http://rosettacode.org/wiki/Remove_lines_from_a_file ... Rod Pemberton
[toc] | [prev] | [next] | [standalone]
| From | Hans Bezemer <the.beez.speaks@gmail.com> |
|---|---|
| Date | 2014-02-13 19:11 +0100 |
| Message-ID | <52fd0ac4$0$2922$e4fe514c@news2.news.xs4all.nl> |
| In reply to | #28366 |
Rod Pemberton wrote:
> On Wed, 12 Feb 2014 20:37:15 -0500, Julian Fondren
> Forth examples are not available for many of the
> Rosetta Code tasks.
> Why is this one of interest to you?
I dunno, but I've solved quite a few - I don't always publish them. This is
the task at hand (in 4tH):
---8<---
include lib/shelsort.4th \ for SORT
include lib/compare.4th \ for COMPARE
4 constant #fields \ number of fields
0 +constant .name \ name the fields
1 +constant .id \ not all of these
2 +constant .salary \ are really required
3 +constant .dept \ for this program
create employees \ create the table
\ Employee Name,Employee ID,Salary,Department
," Tyler Bennett" ," E10297" 32000 , ," D101"
," John Rappl" ," E21437" 47000 , ," D050"
," George Woltman" ," E00127" 53500 , ," D101"
," Adam Smith" ," E63535" 18000 , ," D202"
," Claire Buckman" ," E39876" 27800 , ," D202"
," David McClellan" ," E04242" 41500 , ," D101"
," Rich Holcomb" ," E01234" 49500 , ," D202"
," Nathan Adams" ," E41298" 21900 , ," D050"
," Richard Potter" ," E43128" 15900 , ," D101"
," David Motsinger" ," E27002" 19250 , ," D202"
," Tim Sampair" ," E03033" 27000 , ," D101"
," Kim Arlich" ," E10001" 57000 , ," D190"
," Timothy Grove" ," E16398" 29900 , ," D190"
here employees - #fields / constant #emp
\ calculate the number of employees
#emp array emp-idx \ create an index
emp-idx #emp th equates emp-idx-end \ pointer to end of index
( x n --)
: init-idx 0 do employees i #fields * + over i th ! loop drop ;
\ sort on the department
: sort-on-department ( x n --)
[: >r .dept @c count r> .dept @c count compare 0< ;] is precedes sort
;
\ sort on the salary
: sort-on-salary ( x1 x2 --)
[: >r .salary @c r> .salary @c > ;] is precedes over - sort
;
\ sort on both department and salary
: sort-on-sal/dept ( x n --)
over over sort-on-department \ first sort on department
0 ?do \ go sequentially through index
dup @ .dept @c count emp-idx i th @ .dept @c count compare
if emp-idx i th dup >r sort-on-salary r> then
loop emp-idx-end sort-on-salary \ find department subsets
; \ determine length and sort them
\ display the salaries in a
department
: .salaries ( n x1 x2 -- n)
over - rot dup >r min over @ .dept @c count type space
bounds ?do i @ .salary @c . loop cr r>
; \ no more than first n entries
\ show the top n salaries/department
: top-salaries ( n --)
emp-idx #emp 0 ?do \ go sequentially through index
dup @ .dept @c count emp-idx i th @ .dept @c count compare
if emp-idx i th dup >r .salaries r> then
loop emp-idx-end .salaries drop \ show salaries on department switch
;
emp-idx #emp init-idx \ first create the index
emp-idx #emp sort-on-sal/dept \ now sort it
3 top-salaries cr \ first 2 salaries
1 top-salaries cr \ first salary
200 top-salaries cr \ first 200 salaries
---8<---
>
> Most notably, Forth is not even on the
> *metaprogramming* page:
>
> http://rosettacode.org/wiki/Metaprogramming
>
> Sad...
>
> It's not on many, many others too:
> http://rosettacode.org/wiki/ABC_Problem
Did that one too:
---8<---
offset (blocks) \ initial block data
c" BO" c" XK" c" DQ" c" CP" c" NA"
c" GT" c" RE" c" TG" c" QD" c" FS"
c" JW" c" HU" c" VI" c" AN" c" OB"
c" ER" c" FS" c" LY" c" PC" c" ZM"
0 c, 0 c, \ terminate the blocks
21 constant #blocks \ number of blocks plus one
#blocks 2* buffer: blocks \ allocate the blocks
defer get-letter \ defer comparison
: block@ dup c@ swap char+ c@ ; ( x -- c1 c2)
: block! tuck c! char+ c! ; ( c1 c2 x --)
: block+ 2 chars + ; ( x -- x+2)
: swap-blocks over over block@ 2>r block@ rot block! 2r> rot block! ;
( x1 x2 --)
: init-block ( --)
#blocks 0 ?do i 2* (blocks) i 2* 1+ (blocks) blocks i 2* chars + block!
loop
;
: can-make-word ( a n x -- f)
over if -rot get-letter else true then >r drop drop drop r>
; \ if any string left then do the test
\ otherwise we've done it
:noname ( x a n -- x a n f)
>r >r dup \ store string on return stack
begin \ are there no more blocks?
dup c@ \ if so exit
while \ does the first or second letter
equal
dup dup char+ r@ c@ bl invert and >r c@ r@ = swap c@ r> = or
if \ if so then swap the blocks
over over swap-blocks \ and try for the rest of the letters
over r> r@ over >r chop rot block+ can-make-word >r
over over swap-blocks \ return to the previous state
r@ if drop r> r> r> rot exit else r> drop then
then \ exit if we found a solution
block+ \ if didn't work, try the next block
repeat drop r> r> false \ restore stack diagram, no more
blocks
; is get-letter \ but remember we failed
init-block
s" A" 2dup blocks can-make-word . type cr
s" BARK" 2dup blocks can-make-word . type cr
s" BOOK" 2dup blocks can-make-word . type cr
s" TREAT" 2dup blocks can-make-word . type cr
s" Common" 2dup blocks can-make-word . type cr
s" SQUAD" 2dup blocks can-make-word . type cr
s" Confuse" 2dup blocks can-make-word . type cr
---8<---
Others I find a bit too trivial - or too complex. I don't feel like doing a
lot of programming to produce an alterating series of A's and B's.
Hans Bezemer
[toc] | [prev] | [next] | [standalone]
| From | Julian Fondren <julian.fondren@gmail.com> |
|---|---|
| Date | 2014-02-13 12:08 -0800 |
| Message-ID | <30dc37b6-5be5-4c68-a7c5-1aa3b1e67cfd@googlegroups.com> |
| In reply to | #28387 |
On Thursday, February 13, 2014 2:58:22 AM UTC-6, Rod Pemberton wrote:
> Most notably, Forth is not even on the
>
> *metaprogramming* page:
>
>
>
> http://rosettacode.org/wiki/Metaprogramming
>
It's a bad task for the site. Forth is present on the 'extend your langauge'
task,
http://rosettacode.org/wiki/Extend_your_language
Which asks for "a new flow control mechanism", with a four-way branch as a
specific suggestion:
: fb ( n -- )
dup 5 mod 0= over 3 mod 0=
BOTH ." FizzBuzz "
ELSE ." Fizz "
ORELSE ." Buzz "
ELSE dup .
NEITHER drop ;
: fizzbuzz ( n -- ) 0 do i 1+ fb loop ;
Rather than answer Metaprogramming, I'd rather there were new tasks like
'extend your language' that allowed Forth to demonstrate different kinds of
metaprogramming.
There are after all seemingly limitless mathematic tasks on the site, rather
than a single task that requests a demonstration of each language's total
capacity for mathematics. And instead of an all-inclusive UI task, there are
tasks like Hello world/Graphical:
http://rosettacode.org/wiki/Hello_world/Graphical
For which this is currently the only Forth solution:
HWND z" Goodbye, World!" z" (title)" MB_OK MessageBox
...
On Thursday, February 13, 2014 12:11:18 PM UTC-6, The Beez wrote:
> Others I find a bit too trivial - or too complex. I don't feel like doing a
>
> lot of programming to produce an alterating series of A's and B's.
Sure, but part of the point is that for some languages it's not a lot of
programming. Another is in a language the task is more naturally accomplished
in a different way. And then there incidental comparisons like your sorting
syntax:
: sort-on-salary ( x n --)
[: >r .salary @c r> .salary @c > ;] is precedes sort ;
vs. the very similar Ada:
function Compare_Salary (Left, Right : Employee_Data) return Boolean is
begin
return Left.Salary > Right.Salary;
end Compare_Salary;
package Salary_Sort is new Employee_Vectors.Generic_Sorting
("<" => Compare_Salary);
...
Salary_Sort.Sort (Example_Data);
The most striking solution for me is the SQL one, which I figured would be just
about no code at all, but which actually shows how breath-takingly tedious it
is to use *only SQL* to populate the table and to massage the query results
into nice human-readable output.
-- Julian
[toc] | [prev] | [next] | [standalone]
| From | Hans Bezemer <the.beez.speaks@gmail.com> |
|---|---|
| Date | 2014-02-14 10:57 +0100 |
| Message-ID | <52fde87f$0$2872$e4fe514c@news2.news.xs4all.nl> |
| In reply to | #28390 |
Julian Fondren wrote: > Sure, but part of the point is that for some languages it's not a lot of > programming. Another is in a language the task is more naturally > accomplished > in a different way. Take a look at http://rosettacode.org/wiki/Jensen%27s_Device#Forth I did it in two lines. Not even J is shorter. I also made an awesome Markov engine, but it didn't quite fit the syntax required (hey, this is Forth is it?) so I never posted it. Still, it can easily do stuff like this: # BNF Syntax testing rules rules "A" -> "apple" "WWWW" -> "with" "Bgage" -> "->.*" "B" -> "bag" "->.*" -> "money" "W" -> "WW" "S" -> ."shop" "T" -> "the" "the shop" -> "my brother" "a never used" -> ."terminating rule" = I bought a B of As W my Bgage from T S. Hans Bezemer
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2014-02-14 02:50 -0800 |
| Message-ID | <7x7g8y2ck3.fsf@ruckus.brouhaha.com> |
| In reply to | #28420 |
Hans Bezemer <the.beez.speaks@gmail.com> writes: > Take a look at http://rosettacode.org/wiki/Jensen%27s_Device#Forth > I did it in two lines. Not even J is shorter. I don't think the Forth solution actually does what was asked in the problem. I think it can be done in Forth but it would be messy.
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2014-02-14 11:48 +0000 |
| Subject | Jensen's device (was: Rosetta Code: ...) |
| Message-ID | <2014Feb14.124846@mips.complang.tuwien.ac.at> |
| In reply to | #28420 |
Hans Bezemer <the.beez.speaks@gmail.com> writes:
>Take a look at http://rosettacode.org/wiki/Jensen%27s_Device#Forth
>
>I did it in two lines.
These lines are:
: sum 0 s>f 1+ swap ?do i over execute f+ loop drop ;
:noname s>f 1 s>f fswap f/ ; 1 100 sum f.
Whereas the core of the original is:
print (sum (i, 1, 100, 1/i))
where the parameters are passed by name.
However, you pass i to the :noname definition on the stack, not by
name. The following passes both i and 1/i as an xt:
fvariable ii \ I is a Forth word that we need
: sum ( xt1 lo hi xt2 -- r )
0e swap 1+ rot ?do ( addr xt r1 )
i s>f over execute f! dup execute f+
loop 2drop ;
' ii 1 100 :noname 1e ii f@ f/ ; sum f.
I have added it to the Rosettacode page.
- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2013: http://www.euroforth.org/ef13/
[toc] | [prev] | [next] | [standalone]
| From | Hans Bezemer <the.beez.speaks@gmail.com> |
|---|---|
| Date | 2014-02-14 16:46 +0100 |
| Subject | Re: Jensen's device (was: Rosetta Code: ...) |
| Message-ID | <52fe3a54$0$2863$e4fe514c@news2.news.xs4all.nl> |
| In reply to | #28425 |
Anton Ertl wrote: > Hans Bezemer <the.beez.speaks@gmail.com> writes: >>Take a look at http://rosettacode.org/wiki/Jensen%27s_Device#Forth >> >>I did it in two lines. > > These lines are: > > : sum 0 s>f 1+ swap ?do i over execute f+ loop drop ; > :noname s>f 1 s>f fswap f/ ; 1 100 sum f. > > Whereas the core of the original is: > > print (sum (i, 1, 100, 1/i)) > > where the parameters are passed by name. > > However, you pass i to the :noname definition on the stack, not by > name. The following passes both i and 1/i as an xt: > > fvariable ii \ I is a Forth word that we need > : sum ( xt1 lo hi xt2 -- r ) > 0e swap 1+ rot ?do ( addr xt r1 ) > i s>f over execute f! dup execute f+ > loop 2drop ; > ' ii 1 100 :noname 1e ii f@ f/ ; sum f. > > I have added it to the Rosettacode page. I see the point of your argument, but note the idea of Rosetta code is: how would you solve it in YOUR language. In this case no sane Forth programmer would declare an extra variable - that's the whole idea of Forth. He would pass it as an item on the stack. That's why. Note that as a matter of fact, even C does not pass a NAME, it passes pointers. Passing names is only possible is it is passed by *reference* - something C obviously doesn't support. That my solution can be classified as valid can be determined by what had happend IF it had been passed by value: "If the last parameter to sum had been passed by value, and assuming the initial value of i were 1, the result would have been 100 × 1/1 = 100". Hans Bezemer
[toc] | [prev] | [next] | [standalone]
| From | "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> |
|---|---|
| Date | 2014-02-14 11:30 -0500 |
| Subject | Re: Jensen's device (was: Rosetta Code: ...) |
| Message-ID | <op.xa95g1mh5zc71u@localhost> |
| In reply to | #28428 |
On Fri, 14 Feb 2014 10:46:30 -0500, Hans Bezemer <the.beez.speaks@gmail.com> wrote: > Note that as a matter of fact, even C does not pass a NAME, That's true. Very few languages support passing by name. Take your pick: obscure, useless, obsolete, ill-conceived. > [C] passes pointers. It can. That's called: pass by reference. However, by default, C passes by value. Argumentatively, passing by value is one of C's design flaws. PL/I passes by reference by default which makes it easier to pass parameters. Passing by value is not needed that much. IIRC, Kernighan and Ritchie debated over the best method to pass parameters. > Passing names is only possible [if] it is passed by *reference* - > something C obviously doesn't support. Sorry, but I think it's clear that you're confused... Rod Pemberton
[toc] | [prev] | [next] | [standalone]
| From | Hans Bezemer <the.beez.speaks@gmail.com> |
|---|---|
| Date | 2014-02-14 23:35 +0100 |
| Subject | Re: Jensen's device (was: Rosetta Code: ...) |
| Message-ID | <52fe9a46$0$2925$e4fe514c@news2.news.xs4all.nl> |
| In reply to | #28431 |
Rod Pemberton wrote: > On Fri, 14 Feb 2014 10:46:30 -0500, Hans Bezemer > <the.beez.speaks@gmail.com> wrote: > >> Note that as a matter of fact, even C does not pass a NAME, > > That's true. Very few languages support passing by name. > Take your pick: obscure, useless, obsolete, ill-conceived. > >> [C] passes pointers. > > It can. That's called: pass by reference. > However, by default, C passes by value. Well, how it was explained to me (a very long time ago) is that you manually convert the variable to a "value" (a numerical address) which is passed - hence ONLY passing by value (where C is concerned). The compiler itself does no fancy tricks - you get what you asked for and you'll have to do it yourself if you want it. It worked for me, e.g. I found pointers in C much easier to understand than their equivalents in Pascal. Programming languages that tried to be smarter than me never worked very well for me anyway - hence Forth. Since I have to delve into literature I haven't looked at for the last 30 years, I assume you're right and leave it at that. I think the issue is academical at best. But there still is a difference though between "passing by reference" and "passing by name" - the latter as dead as a dodo, though. Hans Bezemer
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2014-02-15 13:36 +0000 |
| Subject | Re: Jensen's device (was: Rosetta Code: ...) |
| Message-ID | <2014Feb15.143618@mips.complang.tuwien.ac.at> |
| In reply to | #28428 |
Hans Bezemer <the.beez.speaks@gmail.com> writes:
>Anton Ertl wrote:
>
>> Hans Bezemer <the.beez.speaks@gmail.com> writes:
>>>Take a look at http://rosettacode.org/wiki/Jensen%27s_Device#Forth
>>>
>>>I did it in two lines.
>>
>> These lines are:
>>
>> : sum 0 s>f 1+ swap ?do i over execute f+ loop drop ;
>> :noname s>f 1 s>f fswap f/ ; 1 100 sum f.
>>
>> Whereas the core of the original is:
>>
>> print (sum (i, 1, 100, 1/i))
>>
>> where the parameters are passed by name.
>>
>> However, you pass i to the :noname definition on the stack, not by
>> name. The following passes both i and 1/i as an xt:
>>
>> fvariable ii \ I is a Forth word that we need
>> : sum ( xt1 lo hi xt2 -- r )
>> 0e swap 1+ rot ?do ( addr xt r1 )
>> i s>f over execute f! dup execute f+
>> loop 2drop ;
>> ' ii 1 100 :noname 1e ii f@ f/ ; sum f.
>>
>> I have added it to the Rosettacode page.
>I see the point of your argument, but note the idea of Rosetta code is: how
>would you solve it in YOUR language.
It seems to me that the general Rosetta code idea is at odds with the
idea of the "Jensen's device" task then. The example is called
"Jensen's device", not "the 100th harmonic number", and the task
description says: "This task is an exercise in call by name.". Now it
seems to me that, for languages that don't have call-by-name, the task
is to do something that is relatively close to call-by-name, and
that's what I did.
If the task was just "the 100th harmonic number", the Forth solution
(following Chuck Moore's philosophy) is
.( 5.1873775...)
- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2013: http://www.euroforth.org/ef13/
[toc] | [prev] | [next] | [standalone]
| From | albert@spenarnc.xs4all.nl (Albert van der Horst) |
|---|---|
| Date | 2014-02-14 19:12 +0000 |
| Subject | Re: Jensen's device (was: Rosetta Code: ...) |
| Message-ID | <52fe6a9e$0$9228$e4fe514c@dreader35.news.xs4all.nl> |
| In reply to | #28425 |
In article <2014Feb14.124846@mips.complang.tuwien.ac.at>, Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote: >Hans Bezemer <the.beez.speaks@gmail.com> writes: >>Take a look at http://rosettacode.org/wiki/Jensen%27s_Device#Forth >> >>I did it in two lines. > >These lines are: > >: sum 0 s>f 1+ swap ?do i over execute f+ loop drop ; >:noname s>f 1 s>f fswap f/ ; 1 100 sum f. > >Whereas the core of the original is: > >print (sum (i, 1, 100, 1/i)) > >where the parameters are passed by name. > >However, you pass i to the :noname definition on the stack, not by >name. The following passes both i and 1/i as an xt: > >fvariable ii \ I is a Forth word that we need >: sum ( xt1 lo hi xt2 -- r ) > 0e swap 1+ rot ?do ( addr xt r1 ) > i s>f over execute f! dup execute f+ > loop 2drop ; >' ii 1 100 :noname 1e ii f@ f/ ; sum f. > >I have added it to the Rosettacode page. It proves that one can do anything in Forth, but to me Jensen's device should have been dead and buried A.D. 1970. It is a mini-closure made possible by a design error in algol 60 (not repeated in algol 68). > >- anton -- Albert van der Horst, UTRECHT,THE NETHERLANDS Economic growth -- being exponential -- ultimately falters. albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst
[toc] | [prev] | [next] | [standalone]
| From | mhx@iae.nl |
|---|---|
| Date | 2014-02-14 12:13 -0800 |
| Subject | Re: Jensen's device (was: Rosetta Code: ...) |
| Message-ID | <51348468-f015-467a-9b0b-7f2e13f3962d@googlegroups.com> |
| In reply to | #28425 |
On Friday, February 14, 2014 12:48:46 PM UTC+1, Anton Ertl wrote: > Hans Bezemer <the.beez.speaks@gmail.com> writes: > > >Take a look at http://rosettacode.org/wiki/Jensen%27s_Device#Forth > > > >I did it in two lines. > These lines are: > > : sum 0 s>f 1+ swap ?do i over execute f+ loop drop ; > :noname s>f 1 s>f fswap f/ ; 1 100 sum f. > Which is IMHO a clear violation of the intent of JD. > Whereas the core of the original is: > > print (sum (i, 1, 100, 1/i)) > > where the parameters are passed by name. > > However, you pass i to the :noname definition on the stack, not by > name. The following passes both i and 1/i as an xt: > > fvariable ii \ I is a Forth word that we need > : sum ( xt1 lo hi xt2 -- r ) > 0e swap 1+ rot ?do ( addr xt r1 ) > i s>f over execute f! dup execute f+ > loop 2drop ; > ' ii 1 100 :noname 1e ii f@ f/ ; sum f. > > I have added it to the Rosettacode page. : sum ( h l str -- ) ( F: -- r ) dlocal term 0e ?DO I term evaluate F+ LOOP ; : JD ( -- ) #101 1 S" s>f 1/f " sum F. ; FORTH> JD 5.187378 ok ( the correct answer ) -marcel
[toc] | [prev] | [next] | [standalone]
| From | Hans Bezemer <the.beez.speaks@gmail.com> |
|---|---|
| Date | 2014-02-14 23:47 +0100 |
| Subject | Re: Jensen's device (was: Rosetta Code: ...) |
| Message-ID | <52fe9cf7$0$2958$e4fe514c@news2.news.xs4all.nl> |
| In reply to | #28436 |
mhx@iae.nl wrote: > On Friday, February 14, 2014 12:48:46 PM UTC+1, Anton Ertl wrote: >> Hans Bezemer <the.beez.speaks@gmail.com> writes: >> >> >Take a look at http://rosettacode.org/wiki/Jensen%27s_Device#Forth >> > >> >I did it in two lines. >> These lines are: >> >> : sum 0 s>f 1+ swap ?do i over execute f+ loop drop ; >> :noname s>f 1 s>f fswap f/ ; 1 100 sum f. >> > Which is IMHO a clear violation of the intent of JD. The intent of JD was "call by name". However, most of the examples in RC use a local variable or "call by reference". That would defeat almost all implementations in my book. IMHO using the stack for "local variable" is as much a violation as the local variable itself - or the address of a global for that matter. Hans Bezemer
[toc] | [prev] | [next] | [standalone]
| From | mhx@iae.nl |
|---|---|
| Date | 2014-02-14 23:45 -0800 |
| Subject | Re: Jensen's device (was: Rosetta Code: ...) |
| Message-ID | <31c9350b-04ff-4fd8-97e0-1946faf2c906@googlegroups.com> |
| In reply to | #28436 |
On Friday, February 14, 2014 9:13:14 PM UTC+1, m...@iae.nl wrote: [..] > : sum ( h l str -- ) ( F: -- r ) dlocal term 0e ?DO I term evaluate F+ LOOP ; > : JD ( -- ) #101 1 S" s>f 1/f " sum F. ; : 1/i ]] I S>F 1/F [[ ; immediate : sum ( h l -- ) ( F: -- r ) 0e ?DO 1/i F+ LOOP ; : JD ( -- ) #101 1 sum F. ; FORTH> jd 5.187378 ok -marcel
[toc] | [prev] | [next] | [standalone]
| From | mhx@iae.nl |
|---|---|
| Date | 2014-02-15 02:49 -0800 |
| Subject | Re: Jensen's device (was: Rosetta Code: ...) |
| Message-ID | <8564425d-78e5-4518-9a4b-8dce01f71c3c@googlegroups.com> |
| In reply to | #28445 |
On Saturday, February 15, 2014 8:45:49 AM UTC+1, m...@iae.nl wrote: > On Friday, February 14, 2014 9:13:14 PM UTC+1, m...@iae.nl wrote: [..] : sum ( u l 'i-xt a-xt -- ) ( F: -- r ) LOCAL action EXECUTE LOCAL 'i 'i ! 0e BEGIN 'i @ OVER <= WHILE action EXECUTE F+ 1 'i +! REPEAT DROP ; : JD ( -- ) #100 1 [: HERE ;] [: HERE @ S>F 1/F ;] sum F. ; -marcel
[toc] | [prev] | [next] | [standalone]
| From | albert@spenarnc.xs4all.nl (Albert van der Horst) |
|---|---|
| Date | 2014-02-15 11:54 +0000 |
| Subject | Re: Jensen's device (was: Rosetta Code: ...) |
| Message-ID | <52ff556d$0$25265$e4fe514c@dreader34.news.xs4all.nl> |
| In reply to | #28446 |
In article <8564425d-78e5-4518-9a4b-8dce01f71c3c@googlegroups.com>, <mhx@iae.nl> wrote: >On Saturday, February 15, 2014 8:45:49 AM UTC+1, m...@iae.nl wrote: >> On Friday, February 14, 2014 9:13:14 PM UTC+1, m...@iae.nl wrote: >[..] >: sum ( u l 'i-xt a-xt -- ) ( F: -- r ) > LOCAL action EXECUTE LOCAL 'i > 'i ! 0e > BEGIN 'i @ OVER <= > WHILE action EXECUTE F+ > 1 'i +! > REPEAT DROP ; >: JD ( -- ) #100 1 [: HERE ;] [: HERE @ S>F 1/F ;] sum F. ; You should probably use PAD instead of HERE. > >-marcel -- Albert van der Horst, UTRECHT,THE NETHERLANDS Economic growth -- being exponential -- ultimately falters. albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst
[toc] | [prev] | [next] | [standalone]
| From | Hans Bezemer <the.beez.speaks@gmail.com> |
|---|---|
| Date | 2014-02-13 23:20 +0100 |
| Message-ID | <52fd4522$0$2868$e4fe514c@news2.news.xs4all.nl> |
| In reply to | #28387 |
Hans Bezemer wrote:
This one is shorter and more efficient - creates index in one go:
---8<---
include lib/shelsort.4th \ for SORT
include lib/compare.4th \ for COMPARE
4 constant #fields \ number of fields
2 +constant .salary \ offsets to the fields
3 +constant .dept \ in the employees table
create employees \ create the table
\ Employee Name,Employee ID,Salary,Department
," Tyler Bennett" ," E10297" 32000 , ," D101"
," John Rappl" ," E21437" 47000 , ," D050"
," George Woltman" ," E00127" 53500 , ," D101"
," Adam Smith" ," E63535" 18000 , ," D202"
," Claire Buckman" ," E39876" 27800 , ," D202"
," David McClellan" ," E04242" 41500 , ," D101"
," Rich Holcomb" ," E01234" 49500 , ," D202"
," Nathan Adams" ," E41298" 21900 , ," D050"
," Richard Potter" ," E43128" 15900 , ," D101"
," David Motsinger" ," E27002" 19250 , ," D202"
," Tim Sampair" ," E03033" 27000 , ," D101"
," Kim Arlich" ," E10001" 57000 , ," D190"
," Timothy Grove" ," E16398" 29900 , ," D190"
here employees - #fields / constant #emp
\ calculate the number of employees
#emp array emp-idx \ create an index
\ sort on department, salary
:noname ( x1 x2 -- f)
over over >r .dept @c count r> .dept @c count compare dup
if nip nip 0< else drop >r .salary @c r> .salary @c > then
; is precedes
( x n --)
: init-idx tuck 0 do employees i #fields * + over i th ! loop swap sort ;
\ display the salaries in a
department
: .salaries ( n x1 x2 -- n)
over - rot dup >r min over @ .dept @c count type space
bounds ?do i @ .salary @c . loop cr r>
; \ no more than first n entries
\ show the top n salaries/department
: top-salaries ( n --)
emp-idx #emp 0 ?do \ go sequentially through index
dup @ .dept @c count emp-idx i th @ .dept @c count compare
if emp-idx i th dup >r .salaries r> then
loop emp-idx #emp th .salaries drop \ show salaries on department switch
;
emp-idx #emp init-idx \ first create the index
3 top-salaries cr \ first 2 salaries
1 top-salaries cr \ first salary
200 top-salaries cr \ first 200 salaries
---8<---
Hans Bezemer
[toc] | [prev] | [next] | [standalone]
| From | Andrew Haley <andrew29@littlepinkcloud.invalid> |
|---|---|
| Date | 2014-02-13 04:11 -0600 |
| Message-ID | <w-OdndzPJvbYB2HPnZ2dnUVZ_oydnZ2d@supernews.com> |
| In reply to | #28348 |
Hi,
Julian Fondren <julian.fondren@gmail.com> wrote:
>
> Rosetta Code has a 'top rank per group' task:
> http://rosettacode.org/wiki/Top_rank_per_group
>
> employees #employees @ 0 do dup .employee /employee loop drop ;
>
> Second, an always-sorted 'top N' type:
>
> ( top-N array : {max,cur,x*cur} )
> : topn ( n -- a )
> dup 2 + cells dup allocate throw tuck swap erase
> tuck ! 0 over cell+ ! ;
>
> : >topn ( n a -- )
> dup 2@ <> if 1 over cell+ +! then
> dup 2 cells + swap cell+ @ cells bounds do
> dup i @ > if i @ swap i ! then
> cell +loop drop ;
This is a bit ugly, and as a solution doesn't scale at all well:
you're bubble-sorting the top N salaries.
Andrew.
[toc] | [prev] | [next] | [standalone]
| From | humptydumpty <ouatubi@gmail.com> |
|---|---|
| Date | 2014-02-13 10:48 -0800 |
| Message-ID | <4fe368a1-e1f5-40e0-9703-9f69365b57fd@googlegroups.com> |
| In reply to | #28348 |
On Thursday, February 13, 2014 3:37:15 AM UTC+2, Julian Fondren wrote:
> Hello clf,
>
>
>
> Rosetta Code has a 'top rank per group' task:
>
> http://rosettacode.org/wiki/Top_rank_per_group
>
>
>
> Which reads:
>
>
>
> ---
>
> Find the top N salaries in each department, where N is provided as a parameter.
>
> Use this data as a formatted internal data structure (adapt it to your
>
> language-native idioms, rather than parse at runtime), or identify your
>
> external data source:
>
>
>
> Employee Name,Employee ID,Salary,Department
>
> Tyler Bennett,E10297,32000,D101
>
> John Rappl,E21437,47000,D050
>
> George Woltman,E00127,53500,D101
>
> Adam Smith,E63535,18000,D202
>
> Claire Buckman,E39876,27800,D202
>
> David McClellan,E04242,41500,D101
>
> Rich Holcomb,E01234,49500,D202
>
> Nathan Adams,E41298,21900,D050
>
> Richard Potter,E43128,15900,D101
>
> David Motsinger,E27002,19250,D202
>
> Tim Sampair,E03033,27000,D101
>
> Kim Arlich,E10001,57000,D190
>
> Timothy Grove,E16398,29900,D190
>
> ---
>
>
>
> If you look on the page you'll note that there is no Forth solution.
>
>
>
> In general, I think there are three good kinds of solutions to this problem,
>
> with the best depending on your circumstances. They are:
>
>
>
> 1. brute-force the answer with high-level data structures: walk the table,
>
> adding departments as keys to a hash table, the values of which are lists of
>
> salaries. Once you've exhausted the table, sort the keys of the hash (for nice
>
> output) and then print them and their top N of the sorted lists of salaries.
>
>
>
> (If you've never used a Perl oneliner that you wrote in a minute to chew on
>
> multiple repquota streams and spit out the top diskspace-using users, then that
>
> I call this a 'good solution' may puzzle you.)
>
>
>
> 2. feed this table to a relational DBMS and then use SQL to get the answer.
>
>
>
> 3. partially reinvent relational databases. Even if the most advanced text
>
> that you've read is The Manga Guide to Databases, it'll immediately strike you
>
> that the table above may look nice, but... if you split it up and rearrange it
>
> a bit *like so*, it can be much easier to work with...
>
>
>
> There is also, no pun intended and nothing meant by it, a fourth solution:
>
> solve the problem with custom data types and algorithms that are closely
>
> dependent on both the exact query and the exact data.
>
>
>
> I'd like to demonstrate a solution of this last kind.
>
>
>
> First, an uninteresting representation of the employee table: a solid mass of
>
> counted strings.
>
>
>
> : string, ( c-addr u -- )
>
> dup c, here swap dup allot move ;
>
>
>
> variable #employees
>
> : | ( -- )
>
> 1 #employees +!
>
> begin [char] , parse dup while string, repeat 2drop ;
>
>
>
> create employees
>
> \ Employee Name,Employee ID,Salary,Department
>
> | Tyler Bennett,E10297,32000,D101
>
> | John Rappl,E21437,47000,D050
>
> | George Woltman,E00127,53500,D101
>
> | Adam Smith,E63535,18000,D202
>
> | Claire Buckman,E39876,27800,D202
>
> | David McClellan,E04242,41500,D101
>
> | Rich Holcomb,E01234,49500,D202
>
> | Nathan Adams,E41298,21900,D050
>
> | Richard Potter,E43128,15900,D101
>
> | David Motsinger,E27002,19250,D202
>
> | Tim Sampair,E03033,27000,D101
>
> | Kim Arlich,E10001,57000,D190
>
> | Timothy Grove,E16398,29900,D190
>
>
>
> 4 constant #columns
>
>
>
> : .employee ( a -- )
>
> cr #columns 1 do count 2dup type ." , " + loop count type ;
>
>
>
> : /employee ( a -- a' )
>
> #columns 0 do count + loop ;
>
>
>
> : salary ( a -- n )
>
> count + count + count 0. 2swap >number 2drop d>s ;
>
>
>
> : department ( a -- n )
>
> count + count + count + count 0. 2swap 1 /string >NUMBER 2drop d>s ;
>
>
>
> : .employees ( -- )
>
> employees #employees @ 0 do dup .employee /employee loop drop ;
>
>
>
> Second, an always-sorted 'top N' type:
>
>
>
> ( top-N array : {max,cur,x*cur} )
>
> : topn ( n -- a )
>
> dup 2 + cells dup allocate throw tuck swap erase
>
> tuck ! 0 over cell+ ! ;
>
>
>
> : >topn ( n a -- )
>
> dup 2@ <> if 1 over cell+ +! then
>
> dup 2 cells + swap cell+ @ cells bounds do
>
> dup i @ > if i @ swap i ! then
>
> cell +loop drop ;
>
>
>
> : .topn ( a -- )
>
> cell+ dup cell+ swap @ cells bounds ?do i @ . cell +loop ;
>
>
>
> Third, since the departments are numerical and with a small range, and again so
>
> that I don't have to *sort* anything, an array of potential departments with
>
> their values either 0 or a TOPN, and then the final words.
>
>
>
> ( query )
>
> variable max-n
>
>
>
> 300 constant #departments
>
> create departments #departments cells allot
>
>
>
> : >department ( n-salary n-department -- )
>
> cells departments + dup @ if @ >topn
>
> else max-n @ topn tuck swap ! >topn then ;
>
>
>
> : query ( -- ) \ top N salaries by department
>
> departments #departments cells erase
>
> employees #employees @ 0 do
>
> dup salary over department >department
>
> /employee loop drop ;
>
>
>
> : .top-salaries ( -- )
>
> #departments 0 do
>
> i cells departments + @
>
> dup if cr ." D" i 0 .r space .topn else drop
>
> then loop ;
>
>
>
> : top-salaries ( n -- )
>
> max-n ! query .top-salaries ;
>
>
>
> And that's it. No questions about any of that? OK. With user input indented and with extra spacing:
>
>
>
> 3 top-salaries
>
> D50 47000 21900
>
> D101 53500 41500 32000
>
> D190 57000 29900
>
> D202 49500 27800 19250 ok
>
>
>
> 1 top-salaries
>
> D50 47000
>
> D101 53500
>
> D190 57000
>
> D202 49500 ok
>
>
>
> 400 top-salaries
>
> D50 47000 21900
>
> D101 53500 41500 32000 27000 15900
>
> D190 57000 29900
>
> D202 49500 27800 19250 18000 ok
>
>
>
> Although the query is 'top *salaries* by department', now that I look at the
>
> other answers on that page, I see that every one of them provides the employee
>
> record associated with the top salaries. For that, TOPN could have pairs of
>
> (salary,employee record address) cells.
>
>
>
> I haven't submitted this as an answer to the 'Top rank per group' task on
>
> Rosetta Code; I'm more tempted to provide a brute-force-with-high-level-data-structures answer. I'd like to see how you would answer this task.
>
>
>
>
>
> -- Julian
Hi!
Here a primitive network-db (after codasyl) alternative.
I suppose {employees}->{departments} relation is a function,
for every department(codomain) has a ring of employees(domain),
inserted orderly.
It is equivalent with a insert-sort, but I don't bother for now
for too many employees into a department.
: new-node ( -- anode )
HERE DUP ,
;
: do-link ( anode anew-node -- )
OVER @ OVER ! SWAP !
;
WORDLIST CONSTANT DEPT
: $create
S" CREATE " PAD SWAP MOVE
32 UMIN PAD 8 + SWAP MOVE
PAD 40 EVALUATE
;
: new-dm ( $name $??? $sal -- dm-node )
new-node >R
>FLOAT IF F, THEN
STRING,
STRING,
R>
;
: dm>sal ( dm-node -- F: sal )
CELL+ F@
;
: dm>name ( dm-node -- $name )
[ 1 CELLS 1 FLOATS + ] LITERAL +
COUNT + COUNT
;
: new-cdm ( $dept -- cdm-node )
CURRENT @ >R DEPT CURRENT !
$create new-node
R> CURRENT !
;
: search-lesser ( cdm-node dm-node -- dm-node'' dm-node )
OVER >R
BEGIN
OVER @ OVER dm>sal dm>sal F>
IF RDROP EXIT THEN
SWAP @ SWAP
OVER R@ =
IF RDROP EXIT THEN
AGAIN
;
: process ( $name $??? $sal $dept -- )
2DUP DEPT SEARCH-WORDLIST
IF
NIP NIP EXECUTE
ELSE
new-cdm
THEN ( $name $??? $sal cdm-node )
>R new-dm R> SWAP ( cdm-node dm-node )
OVER DUP @ <> ( non-empty ring )
IF
search-lesser
THEN
do-link
;
: .top ( n cdm-node -- )
TUCK 2>R
0 SWAP @
BEGIN ( contor node )
2DUP 2R@ ( contor node contor node limit limit-node )
ROT = -ROT = OR
IF 2RDROP 2DROP EXIT THEN
DUP dm>sal F. DUP dm>name TYPE CR
@ SWAP 1+ SWAP
AGAIN
;
: .dept ( n -- )
DEPT CELL+ @
BEGIN
DUP
WHILE
DUP ID. CR
2DUP NAME>INT EXECUTE .top
@
REPEAT
2DROP
;
: run
BEGIN
REFILL
WHILE
[CHAR] , PARSE [CHAR] , PARSE [CHAR] , PARSE [CHAR] , PARSE
process
REPEAT
;
: @top# ( -- n )
1 arg 0 0 2SWAP >NUMBER 2DROP D>S
;
STDIN ' run EXECUTE-PARSING-FILE @top# .dept bye
Now testing:
bash-4.2$ cat data.txt
Tyler Bennett,E10297,32000,D101
John Rappl,E21437,47000,D050
George Woltman,E00127,53500,D101
Adam Smith,E63535,18000,D202
Claire Buckman,E39876,27800,D202
David McClellan,E04242,41500,D101
Rich Holcomb,E01234,49500,D202
Nathan Adams,E41298,21900,D050
Richard Potter,E43128,15900,D101
David Motsinger,E27002,19250,D202
Tim Sampair,E03033,27000,D101
Kim Arlich,E10001,57000,D190
Timothy Grove,E16398,29900,D190
bash-4.2$ gforth dpt.fs < data.txt
D190
D202
D050
D101
bash-4.2$ gforth dpt.fs 2 < data.txt
D190
57000. Kim Arlich
29900. Timothy Grove
D202
49500. Rich Holcomb
27800. Claire Buckman
D050
47000. John Rappl
21900. Nathan Adams
D101
53500. George Woltman
41500. David McClellan
bash-4.2$ gforth dpt.fs 10 < data.txt
D190
57000. Kim Arlich
29900. Timothy Grove
D202
49500. Rich Holcomb
27800. Claire Buckman
19250. David Motsinger
18000. Adam Smith
D050
47000. John Rappl
21900. Nathan Adams
D101
53500. George Woltman
41500. David McClellan
32000. Tyler Bennett
27000. Tim Sampair
15900. Richard Potter
Enough testing! :)
Have a nice day,
humptydumpty
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.forth
csiph-web