Author Topic: Generate Finnish reference number  (Read 3048 times)

Offline jalih

  • Advocate
  • Posts: 111
Generate Finnish reference number
« on: November 29, 2018, 05:56:46 AM »
In your favorite programming language, create application that can generate valid Finnish reference numbers (yeah, you guessed it, I am from Finland...). GUI is optional, not required.

Code: [Select]

: strip-leading-zeros  \ s -- s
  /^0+/ s:/ "" a:join ;


: format  \ s -- s
  s:rev
  "5:5b" unpack drop ' >s a:map
  " " a:join s:rev ;


: numbers?  \ s -- s f
  dup /[^0-9]/ r:match nip
  0 n:= if
    true
  else
    false
  then ;


: rand0-9
  rand-pcg n:abs 10 n:mod ;


: rand1-9
  rand-pcg n:abs 9 n:mod n:1+ ;


: random-ref?  \ n -- viite
  >r r@ 3 19 n:between not if
    rdrop null
  else
    ( 0 n:= if rand1-9 else rand0-9 then >s ) 0 r@ n:1- loop
    r> a:close "" a:join
  then ;


: +check?  \ viite -- viite+tarkiste
  " " "" s:replace!
  strip-leading-zeros numbers? if
    dup s:len 3 19 n:between not if
      2drop null
    else
      "" s:/
      a:new >r ( >n [ 1, 3, 7 ] rot 3 n:mod a:@ nip n:* r@ swap a:push drop ) a:each drop r>
      ' n:+ 0 a:reduce dup 10 n:/ n:ceil 10 n:* n:int swap n:- 10 n:mod >s s:+
    then
  else
    drop null
  then ;


: validate  \ viite -- f
  " " "" s:replace!
  strip-leading-zeros numbers? if
    -1 s:@ "" swap s:+ >n >r
    s:len n:1- 1 s:-
    s:len 3 19 n:between not if
      drop false
    else
      "" s:/
      a:new >r ( >n [ 1, 3, 7 ] rot 3 n:mod a:@ nip n:* r@ swap a:push drop ) a:each drop r>
      ' n:+ 0 a:reduce dup 10 n:/ n:ceil 10 n:* n:int swap n:- 10 n:mod r> n:=
    then
  else
    drop null
  then ;


: do-ref  \ n -- viitenumero
  n:1- random-ref? null? if ;; then
  +check?
  format ;


\
\ --------------------------------------------------------------------------------------------------------------------------
\

true app:isgui !

4 var, length


: generate
  "edit" g:child length @ do-ref g:text drop ;


var gui

{
  "kind" : "win",
  "buttons" : 5,
  "title" : "Reference number generator",
  "wide" : 320,
  "high" : 200,
  "min-wide" : 320,
  "min-high" : 200,
  "max-wide" : 320,
  "max-high" : 200,
  "bg":"lightgray",
  "center" : true,
  "children" :
  [
    {
      "kind" : "box",
      "name" : "box1",
      "bounds" : "20, 20, parent.width-20, parent.height-20",
      "bg":"gray",
      "children" :
      [
        {
          "kind" : "label",
          "label" : "\nChoose length for reference number:",
          "bounds": "parent.left, parent.top-20, parent.width-20, top+40 ",
          "justify" : ["hcenter"],
          "name" : "lbl"
},
        {
          "kind" : "combo",
          "bounds" : "parent.left, lbl.bottom+10, left+50, top+30",
          "bg"   : "white",
          "name" : "combo",
          "changed" : ( drop 4 n:+ length ! drop ) ,
          "tooltip" : "Length of reference number",
          "selected" : 0,
          "items" : [ "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14" , "15", "16", "17","18", "19", "20" ]
        },
        {
          "kind" : "btn",
          "label" : "Generate",
          "bg" : "purple",
          "bounds" : "combo.right+20, combo.top, lbl.right, top+30",
          "name" : "button",
          "tooltip" : "Generate reference number",
          "click" : "generate"
        },
        {
          "kind" : "edit",
          "empty-text" : "Reference number",
          "bounds" : "parent.left, combo.bottom+30, lbl.right, top+24",
          "name" : "edit",
          "bg"   : "aquamarine1",
          "ro"   : true,
          "tooltip" : "Reference number"
        }
      ]
    }
  ]
} var, gui-desc


: app:main
  gui-desc @ g:new gui ! ;