Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: Algorithm challenge: compacting intege...

From: Paavo:Nevalainen:saunalahti:fi at: 28-Jan-2007 23:21

Humor alert! I decided to do what a usual salaryman would do, i.e. a lot of slow code! And documentation and unit tests (not complete though). The cumulator pattern is sometimes useful, when one prepares to test a single "tic" of the loop in a unit test. I have indicated the "internal" functions or methods with the initial "_", just a convention when modules are not yet here. ================================================= ; these two "beautifying" functions from some "module" ... case: function [{ Find a condition and evaluates what follows it. Usage: case/default [ cond1 do-block1 ...][default-do-block] } [throw] cases [block!] "Block of cases to evaluate." /default case "Default case if no others are found." ][ condition body ][ while [not empty? cases][ set [condition cases] do/next cases if condition [ body: first cases break ] cases: next cases ] if not body [body: any [case]] do body ] _test: function [ boiler [string! block!] val ][ str ][ if block? boiler [str: rejoin boiler] print rejoin [boiler ": " mold val] return val ] ;-=--0_---____------------------------------------ compact: function [{ compact [1 2 3 5 2001 2002 2003 2004 2007 ..] --> [1x3 5 2001x4 2007 ..] } ys [block!] ][ cumulator y ][ cumulator: make object! [ result: make block! [] interval-first: none interval-last: none _to-string: does [ return rejoin [ "result: " mold self/result " x1: " self/interval-first " x2: " self/interval-last ] ] tic: func [ y ][ ; print reduce [mold self/_to-string " y: " y] case/default [ ; the start case! none? self/interval-first [ self/interval-first: y ] ; an interval found :) ; [.. y1-1 none] ** [y1 y2 ..] --> [.. y0 y0+1] all [none? self/interval-last (y - 1) = self/interval-first][ self/interval-last: y ] ; a solo number found :( ; [.. y0 none] ** [y1 y2 ..] --> [[.. y0] y1 none] ** [y2 ..] none? self/interval-last [ append self/result self/interval-first self/interval-first: y ] ; interval keeps growing! :D ; [.. y y1-1] ** [y1 y2 ..] --> [.. y y1] ** [y2 ..] self/interval-last = (y - 1) [ self/interval-last: y ] ][ ; well, this interval did not last to the very end :| self/_add-interval self/interval-first: y ] ] finalize: does [ either none? self/interval-last [ if not none? self/interval-first [ append self/result self/interval-first ] ][ self/_add-interval ] ] ; an internal method... _add-interval: does [ ; adds a new interval to the result append self/result to-pair reduce [ self/interval-first self/interval-last + 1 - self/interval-first ] self/interval-first: none self/interval-last: none ] ] foreach y ys [cumulator/tic y] cumulator/finalize return cumulator/result ] _decompact: function [ p [pair!] ][ out y dummy ][ out: make block! [] y: p/1 repeat dummy p/2 [ append out y y: y + 1 ] return out ] decompact: function [{ decompact [1x3 5 2001x4 2007 ..] --> [1 2 3 5 2001 2002 2003 2004 2007 ..] } xs [block!] ][ out ][ out: make block! [] foreach x xs [ append out either pair? x [_decompact x][x] ] return out ] ;------------------------------,..,,.,..,,..,11,.,.----------- test: has [ result0 result1 result2 ][ result1: _test rejoin ["compact " mold result0: [1 2 3 5 2001 2002 2003 2004 2007]] compact result0 _test "compact [] " compact [] result2: _test ["decompact compact " mold result0] decompact result1 _test "compact decompact ... ??" compact decompact result1 _test rejoin [(mold result0) " = " (mold result2) "? "] (mold result0) = (mold result2) ]