(require 'struct)
(require 'hash)
(require 'sql)

(define H (make-hash))
(define T (make-table (struct goodies (name poids valeur ))))
(define-syntax-rule (name i) (table-xref T i 0))
(define-syntax-rule (poids i) (table-xref T i 1))
(define-syntax-rule (valeur i) (table-xref T i 2))

;;  make an unique hash-key from (i rest)
(define (t-idx i r)  (string-append i "|" r))
;; retrieve best score for item i, remaining r availbble weight
(define (t-get i r)  (or (hash-ref H (t-idx i r)) 0))

;; compute best score (i), assuming best (i-1 rest) is known
(define (score i restant)
	(if (< i 0) 0
	(hash-ref! H (t-idx i restant)
		(if ( >= restant (poids i))
			(max
				(score (1- i) restant)
			    (+ (score (1- i) (- restant (poids i))) (valeur i)))
		    (score (1- i) restant)))))

;; compute best scores, starting from last item
(define (task W)
        (define restant W)
        (define N (1- (table-count T)))
		(writeln 'total-value (score N W))
		(for/list  ((i (in-range N -1 -1)))
			#:continue (= (t-get i restant) (t-get (1- i) restant))
			(set! restant (- restant (poids i)))
			(name i)))


# Project : Jensen's Device

decimals(14)
i = 100
see sum(i,1,100,"1/n") + nl

func sum(i,lo,hi,term)
        temp = 0
        for n = lo to hi step 1
             eval("num = " + term)
             temp = temp + num
        next
        return temp


def sum(var, lo, hi, term, context)
  sum = 0.0
  lo.upto(hi) do |n|
    sum += eval "#{var} = #{n}; #{term}", context
  end
  sum
end
p sum "i", 1, 100, "1.0 / i", binding   # => 5.18737751763962


use std::f32;

fn harmonic_sum<F>(lo: usize, hi: usize, term: F) -> f32
where
    F: Fn(f32) -> f32,
{
    (lo..hi + 1).fold(0.0, |acc, item| acc + term(item as f32))
}

fn main() {
    println!("{}", harmonic_sum(1, 100, |i| 1.0 / i));
}


class MyInt { var i: Int = _ }
val i = new MyInt
def sum(i: MyInt, lo: Int, hi: Int, term: => Double) = {
  var temp = 0.0
  i.i = lo
  while(i.i <= hi) {
    temp = temp + term
    i.i += 1
  }
  temp
}
sum(i, 1, 100, 1.0 / i.i)


(define-syntax sum
  (syntax-rules ()
    ((sum var low high . body)
     (let loop ((var low)
                (result 0))
       (if (> var high)
           result
           (loop (+ var 1)
                 (+ result . body)))))))


// version 1.2.21

data class JsonObject(val foo: Int, val bar: Array<String>)

data class JsonObject2(val ocean: String, val blue: Array<Int>)

fun main(args: Array<String>) {
    // JSON to object
    val data: JsonObject = JSON.parse("""{ "foo": 1, "bar": ["10", "apples"] }""")
    println(JSON.stringify(data))

    // object to JSON
    val data2 = JsonObject2("water", arrayOf(1, 2))
    println(JSON.stringify(data2))
}


// Javascript objects are represented by maps in Lasso
local(mymap = map(
	'success'	= true,
	'numeric'	= 11,
	'string'	= 'Eleven'
))

json_serialize(#mymap) // {"numeric": 11,"string": "Eleven","success": true}
'
'

// Javascript arrays are represented by arrays
local(opendays = array(
	'Monday',
	'Tuesday'
))

local(closeddays = array(
	'Wednesday',
	'Thursday',
	'Friday'
))

json_serialize(#opendays) // ["Monday", "Tuesday"]
'
'
json_serialize(#closeddays) // ["Wednesday", "Thursday", "Friday"]
'
'

#mymap -> insert('Open' = #opendays)
#mymap -> insert('Closed' = #closeddays)

local(myjson = json_serialize(#mymap))
#myjson // {"Closed": ["Wednesday", "Thursday", "Friday"],"numeric": 11,"Open": ["Monday", "Tuesday"],"string": "Eleven","success": true}
'
'

json_deserialize(#myjson) // map(Closed = array(Wednesday, Thursday, Friday), numeric = 11, Open = array(Monday, Tuesday), string = Eleven, success = true)


(: jiffy encode (list 1 2 3 '"apple" 'true 3.14))


class
	APPLICATION

create
	make

feature {NONE} -- Initialization

	make
		local
			knapsack: KNAPSACKZEROONE
		do
			create knapsack.make (400)
			knapsack.add_item (create {ITEM}.make ("", 0, 0))
			knapsack.add_item (create {ITEM}.make ("map", 9, 150))
			knapsack.add_item (create {ITEM}.make ("compass", 13, 35))
			knapsack.add_item (create {ITEM}.make ("water", 153, 200))
			knapsack.add_item (create {ITEM}.make ("sandwich", 50, 160))
			knapsack.add_item (create {ITEM}.make ("glucose", 15, 60))
			knapsack.add_item (create {ITEM}.make ("tin", 68, 45))
			knapsack.add_item (create {ITEM}.make ("banana", 27, 60))
			knapsack.add_item (create {ITEM}.make ("apple", 39, 40))
			knapsack.add_item (create {ITEM}.make ("cheese", 23, 30))
			knapsack.add_item (create {ITEM}.make ("beer", 52, 10))
			knapsack.add_item (create {ITEM}.make ("suntan cream", 11, 70))
			knapsack.add_item (create {ITEM}.make ("camera", 32, 30))
			knapsack.add_item (create {ITEM}.make ("T-shirt", 24, 15))
			knapsack.add_item (create {ITEM}.make ("trousers", 48, 10))
			knapsack.add_item (create {ITEM}.make ("umbrella, ella ella", 73, 40))
			knapsack.add_item (create {ITEM}.make ("waterproof trousers", 42, 70))
			knapsack.add_item (create {ITEM}.make ("waterproof overclothes", 43, 75))
			knapsack.add_item (create {ITEM}.make ("note-case", 22, 80))
			knapsack.add_item (create {ITEM}.make ("sunglasses", 7, 20))
			knapsack.add_item (create {ITEM}.make ("towel", 18, 12))
			knapsack.add_item (create {ITEM}.make ("socks", 4, 50))
			knapsack.add_item (create {ITEM}.make ("book", 30, 10))
			knapsack.compute_solution
		end

end


$ include "seed7_05.s7i";
  include "float.s7i";

var integer: i is 0;

const func float: sum (inout integer: i, in integer: lo, in integer: hi,
    ref func float: term) is func
  result
    var float: sum is 0.0
  begin
    for i range lo to hi do
      sum +:= term;
    end for;
  end func;

const proc: main is func
  begin
   writeln(sum(i, 1, 100, 1.0/flt(i)) digits 6);
  end func;


var i;
func sum (i, lo, hi, term) {
    var temp = 0;
    for (*i = lo; *i <= hi; (*i)++) {
        temp += term.run;
    };
    return temp;
};
say sum(\i, 1, 100, { 1 / i });


comment Jensen's Device;
begin
   integer i;
   real procedure sum (i, lo, hi, term);
      name i, term;
      value lo, hi;
      integer i, lo, hi;
      real term;
      comment term is passed by-name, and so is i;
   begin
      integer j;
      real temp;
      temp := 0;
      for j := lo step 1 until hi do
      begin
         i := j;
         temp := temp + term
      end;
      sum := temp
   end;
   comment note the correspondence between the mathematical notation and the call to sum;
   outreal (sum (i, 1, 100, 1/i), 7, 14)
end


val i = ref 42 (* initial value doesn't matter *)

fun sum' (i, lo, hi, term) = let
  val result = ref 0.0
in
  i := lo;
  while !i <= hi do (
    result := !result + term ();
    i := !i + 1
  );
  !result
end

val () =
  print (Real.toString (sum' (i, 1, 100, fn () => 1.0 / real (!i))) ^ "\n")


var i = 42 // initial value doesn't matter

func sum(inout i: Int, lo: Int, hi: Int, @autoclosure term: () -> Double) -> Double {
  var result = 0.0
  for i = lo; i <= hi; i++ {
    result += term()
  }
  return result
}

println(sum(&i, 1, 100, 1 / Double(i)))


proc sum {var lo hi term} {
    upvar 1 $var x
    set sum 0.0
    for {set x $lo} {$x < $hi} {incr x} {
        set sum [expr {$sum + [uplevel 1 [list expr $term]]}]
    }
    return $sum
}
puts [sum i 1 100 {1.0/$i}] ;# 5.177377517639621


//--------------------------------------
// Simple (unsafe) JSON decoder based on eval()
// @param {string} json
// @return {any}
//--------------------------------------
function json_decode (json){
  var o;
  eval('o='+json);
  return _json_decode_val(o);
}

function _json_decode_val (o){
  if (o==null) return undefined;
  switch(typeof(o)){
    case "object":
      if (o instanceof Array){
        var v = list();
        var cnt = o.length;
        for (i=0;i<cnt;i++){
          v.add(_json_decode_val(o[i]));
        }
      }else{
        var v = propList();
        for (var i in o){
          var p = i;
          v.setAProp(_json_decode_val(p), _json_decode_val(o[i]));
        }
      }
      return v;
    case "string":
      // optional support of special Lingo data type 'symbol' unknown to JavaScript
      if (o.substr(0,7)=='__sym__') return symbol(o.substr(7));
      return o;
    default:
      return o;
  }
}

function _json_escape_string (str){
  var hash={"\\":"\\\\", "/":"\\/", "\n":"\\n", "\t":"\\t", "\r":"\\r", "\b":"\\b", "\f":"\\f", "\"":"\\\""};
  var patt = "["; for (i in hash) patt+=i;patt+="]";
  return str.replace(RegExp(patt, "g"), function(c){
    return hash[c]
  });
}


local json = require("json")

local json_data = [=[[
    42,
    3.14159,
    [ 2, 4, 8, 16, 32, 64, "apples", "bananas", "cherries" ],
    { "H": 1, "He": 2, "X": null, "Li": 3 },
    null,
    true,
    false
]]=]

print("Original JSON: " .. json_data)
local data = json.decode(json_data)
json.util.printValue(data, 'Lua')
print("JSON re-encoded: " .. json.encode(data))

local data = {
    42,
    3.14159,
    {
        2, 4, 8, 16, 32, 64,
        "apples",
        "bananas",
        "cherries"
    },
    {
        H = 1,
        He = 2,
        X = json.util.null(),
        Li = 3
    },
    json.util.null(),
    true,
    false
}

print("JSON from new Lua data: " .. json.encode(data))


defmodule Knapsack do
  def solve([], _total_weight, item_acc, value_acc, weight_acc), do:
    {item_acc, value_acc, weight_acc}
  def solve([{_item, item_weight, _item_value} | t],
            total_weight,
            item_acc,
            value_acc,
            weight_acc) when item_weight > total_weight, do:
    solve(t, total_weight, item_acc, value_acc, weight_acc)
  def solve([{item_name, item_weight, item_value} | t],
            total_weight,
            item_acc,
            value_acc,
            weight_acc) do
    {_tail_item_acc, tail_value_acc, _tail_weight_acc} = tail_res =
        solve(t, total_weight, item_acc, value_acc, weight_acc)
    {_head_item_acc, head_value_acc, _head_weight_acc} = head_res =
        solve(t,
              total_weight - item_weight,
              [item_name | item_acc],
              value_acc + item_value,
              weight_acc + item_weight)
    if tail_value_acc > head_value_acc, do: tail_res, else: head_res
  end
end

stuff = [{"map",                      9,   150},
         {"compass",                 13,    35},
         {"water",                  153,   200},
         {"sandwich",                50,   160},
         {"glucose",                 15,    60},
         {"tin",                     68,    45},
         {"banana",                  27,    60},
         {"apple",                   39,    40},
         {"cheese",                  23,    30},
         {"beer",                    52,    10},
         {"suntan cream",            11,    70},
         {"camera",                  32,    30},
         {"T-shirt",                 24,    15},
         {"trousers",                48,    10},
         {"umbrella",                73,    40},
         {"waterproof trousers",     42,    70},
         {"waterproof overclothes",  43,    75},
         {"note-case",               22,    80},
         {"sunglasses",               7,    20},
         {"towel",                   18,    12},
         {"socks",                    4,    50},
         {"book",                    30,    10}]
max_weight = 400

go = fn (stuff, max_weight) ->
  {time, {item_list, total_value, total_weight}} = :timer.tc(fn ->
    Knapsack.solve(stuff, max_weight, [], 0, 0)
  end)
  IO.puts "Items:"
  Enum.each(item_list, fn item -> IO.inspect item end)
  IO.puts "Total value: #{total_value}"
  IO.puts "Total weight: #{total_weight}"
  IO.puts "Time elapsed in milliseconds: #{time/1000}"
end
go.(stuff, max_weight)


(defun ks (max-w items)
  (let ((cache (make-vector (1+ (length items)) nil)))
    (dotimes (n (1+ (length items)))
      (setf (aref cache n) (make-hash-table :test 'eql)))
    (defun ks-emb (spc items)
      (let ((slot (gethash spc (aref cache (length items)))))
        (cond
         ((null items) (list 0 0 '()))
         (slot slot)
         (t (puthash spc
                  (let*
                      ((i (car items))
                       (w (nth 1 i))
                       (v (nth 2 i))
                       (x (ks-emb spc (cdr items))))
                    (cond
                     ((> w spc) x)
                     (t
                      (let* ((y (ks-emb (- spc w) (cdr items)))
                             (v (+ v (car y))))
                        (cond
                         ((< v (car x)) x)
                         (t
                          (list v (+ w (nth 1 y)) (cons i (nth 2 y)))))))))
                  (aref cache (length items)))))))
    (ks-emb max-w items)))

(ks 400
    '((map 9 150) (compass 13 35) (water 153 200) (sandwich 50 160)
      (glucose 15 60) (tin 68 45)(banana 27 60) (apple 39 40)
      (cheese 23 30) (beer 52 10) (cream 11 70) (camera 32 30)
      (T-shirt 24 15) (trousers 48 10) (umbrella 73 40)
      (waterproof-trousers 42 70) (overclothes 43 75) (notecase 22 80)
      (glasses 7 20) (towel 18 12) (socks 4 50) (book 30 10)))


Private Function sum(i As String, ByVal lo As Integer, ByVal hi As Integer, term As String) As Double
    Dim temp As Double
    For k = lo To hi
        temp = temp + Evaluate(Replace(term, i, k))
    Next k
    sum = temp
End Function
Sub Jensen_Device()
    Debug.Print sum("i", 1, 100, "1/i")
    Debug.Print sum("i", 1, 100, "i*i")
    Debug.Print sum("j", 1, 100, "sin(j)")
End Sub


class Box {
    construct new(v) { _v = v }
    v { _v }
    v=(value) { _v = value }
}

var i = Box.new(0)  // any initial value will do here

var sum = Fn.new { |i, lo, hi, term|
    var temp = 0
    i.v = lo
    while (i.v <= hi) {
        temp = temp + term.call()
        i.v = i.v + 1
    }
    return temp
}

var s = sum.call(i, 1, 100, Fn.new { 1/i.v })
System.print(s)


sub Evaluation()
    lo = 1 : hi = 100 : temp = 0
    for i = lo to hi
        temp = temp + (1/i)  //r(i)
    next i
    print temp
end sub

Evaluation()


fcn sum(ri, lo,hi, term){
   temp:=0.0; ri.set(lo);
   do{ temp+=term(ri); } while(ri.inc()<hi); // inc return previous value
   return(temp);
}
sum(Ref(0), 1,100, fcn(ri){ 1.0/ri.value }).println();


10 DEF FN r(x)=1/x
20 LET f$="FN r(i)"
30 LET lo=1: LET hi=100
40 GO SUB 1000
50 PRINT temp
60 STOP
1000 REM Evaluation
1010 LET temp=0
1020 FOR i=lo TO hi
1030 LET temp=temp+VAL f$
1040 NEXT i
1050 RETURN


MODULE A {
      \\ Process data in json format

      \\ We can load from external file with Inline "libName"
      \\ or multiple files Inline "file1" && "file2"
      \\ but here we have the library in a module
      Inline Code Lib1
      \\ So now we make a Parser object (a group type in M2000)
      Parser=ParserClass()
      \\ We can display any function, module that is public and known list
      Modules ?
      \\ And this are all known variables (or and objects)
      List !
      Document json$
      \\ We can load from file
      \\ Load.Doc json$, "alfa.json"
      json$={{
            "alfa":-0.11221e+12,
            "array" : [
                  -0.67,
                  "alfa1",
                  [
                        10,
                        20
                  ],
                  "beta1",
                  1.21e12,
                  21.12145,
                  "ok"
            ],
            "delta": false, "epsilon" : true, "Null Value" : null
      }}
      Save.Doc json$, "json2.json"    \\ by default in Utf-8 with BOM
      \\ just show multiline text
      \\ Report display lines and stop after 3/4 of console height lines
      \\ just press a key or click mouse button
      Report json$
      \\ so now we get text to a new object
      alfa=Parser.Eval(json$)
      \\ check it
      Print Type$(alfa) ' it is a group
      Print "alfa.type$=";alfa.type$ \\ this is a read only property

      Report "as one line"
      Report Parser.Ser$(alfa, 0)

      Report "as multiline"
      Report Parser.Ser$(alfa, 1)

      Print "Using Print"
      Print Parser.ReadAnyString$(alfa)

      Print "Value for alfa, id alfa"
      Print Parser.ReadAnyString$(alfa,"alfa")
      Report "as multiline"
      Report Parser.Ser$(Parser.Eval(Parser.ReadAnyString$(alfa,"array", 2)), 1)
      \\ We get a copy of an array as a Group (a group which return an array)
      Alfa3=Parser.Eval(Parser.ReadAnyString$(alfa,"array", 2))
      \\ First value is for actual object, second value is a readonly property of this object
      Print type$(Alfa3), Alfa3.type$
      Dim B()
      \\ Now Alfa3 run Value part and pass a pointer of array
      \\  B() is an array and here take a pointer to Alfa3 array (as value of Alfa3)
      B()=Alfa3
      \\ each() make an iterator for B()
      N=each(B())
      While N {
            \\ Using B() we get values always. but if we have "object" or "array" then Print prints items **
            Print B(N^)
      }
      \\ Print show here nothing because if value is object then "print" just leave a column and continue to next one
      Print B()
      \\ we have to use Group() to get group not value of group (if any).
      \\ Group() works for "named" group, not for stored in an array or an inventory or a stack
      Print Parser.StringValue$(Group(Alfa3), 0)
      Print Parser.StringValue$(Group(Alfa3), 1)
      \\ Now we want to pass a new value
      \\ Interpreter want to match type of expression from left side to right side
      \\ Because Parser.StringValue$ is actual a Group (As property),
      \\ we have a second linked name:  Parser.StringValue
      \\ we have to use Parser.StringValue()
      \\ and all values must be groups, as those provided by Parser
      Parser.StringValue(Group(Alfa3), 1)=Parser.Numeric(1234)
      Print Parser.StringValue$(Group(Alfa3), 1)
      Print Parser.StringValue$(Group(Alfa), "array", 2, 0)
      \\ we have to use Parser.StringValue$()
      Parser.StringValue$(Group(Alfa), "array", 2, 0)=Parser.JString$("Changed to String")
      Print Parser.StringValue$(Group(Alfa), "array", 2,0)
      Try ok {
            Print Parser.StringValue$(Group(Alfa), "array", 2)
      }
      If Error or not ok Then Print Error$
      Parser.StringValue.Add = True
      Parser.StringValue$(Group(Alfa), "array", 2, 10)=Parser.JString$("Changed to String 2")
      Parser.StringValue(Group(Alfa), "Last value")=Parser.Boolean(true)
      Report "as multiline"
      Report Parser.Ser$(alfa3, 1)
      Report Parser.Ser$(alfa, 1)
      Parser.StringValue.Add = False
      Parser.StringValue.Del = True
      Parser.StringValue(Group(Alfa), "array", 0)=Parser.Null()
      Parser.StringValue(Group(Alfa), "delta")=Parser.Null()
      Parser.StringValue.Del = False
      For Parser {
            .StringValue(Group(Alfa), "array", 1,5)=.Arr((.Numeric(10), .Jstring$("ok 20"), .Boolean(true)))
      }
      Report Parser.Ser$(alfa, 1)

}
// call A
A


> JSON:-ParseString("[{\"tree\": \"maple\", \"count\": 21}]");
       [table(["tree" = "maple", "count" = 21])]
> JSON:-ToString( [table(["tree" = "maple", "count" = 21])] );
       "[{\"count\": 21, \"tree\": \"maple\"}]"


data = ImportString["{ \"foo\": 1, \"bar\": [10, \"apples\"] }","JSON"]
ExportString[data, "JSON"]


>> jsondecode('{ "foo": 1, "bar": [10, "apples"] }')
ans =
  struct with fields:

    foo: 1
    bar: {2×1 cell}
>> jsonencode(ans)
ans =
{"foo":1,"bar":[10,"apples"]}


-module(knapsack_0_1).

-export([go/0,
         solve/5]).

-define(STUFF,
        [{"map",                      9,   150},
         {"compass",                 13,    35},
         {"water",                  153,   200},
         {"sandwich",                50,   160},
         {"glucose",                 15,    60},
         {"tin",                     68,    45},
         {"banana",                  27,    60},
         {"apple",                   39,    40},
         {"cheese",                  23,    30},
         {"beer",                    52,    10},
         {"suntan cream",            11,    70},
         {"camera",                  32,    30},
         {"T-shirt",                 24,    15},
         {"trousers",                48,    10},
         {"umbrella",                73,    40},
         {"waterproof trousers",     42,    70},
         {"waterproof overclothes",  43,    75},
         {"note-case",               22,    80},
         {"sunglasses",               7,    20},
         {"towel",                   18,    12},
         {"socks",                    4,    50},
         {"book",                    30,    10}
        ]).

-define(MAX_WEIGHT, 400).

go() ->
    StartTime = os:timestamp(),
    {ItemList, TotalValue, TotalWeight} =
        solve(?STUFF, ?MAX_WEIGHT, [], 0, 0),
    TimeElapsed = timer:now_diff(os:timestamp(), StartTime),
    io:format("Items: ~n"),
    [io:format("~p~n", [Item]) || Item <- ItemList],
    io:format(
      "Total value: ~p~nTotal weight: ~p~nTime elapsed in milliseconds: ~p~n",
      [TotalValue, TotalWeight, TimeElapsed/1000]).

solve([], _TotalWeight, ItemAcc, ValueAcc, WeightAcc) ->
    {ItemAcc, ValueAcc, WeightAcc};
solve([{_Item, ItemWeight, _ItemValue} | T],
      TotalWeight,
      ItemAcc,
      ValueAcc,
      WeightAcc) when ItemWeight > TotalWeight ->
    solve(T, TotalWeight, ItemAcc, ValueAcc, WeightAcc);
solve([{ItemName, ItemWeight, ItemValue} | T],
      TotalWeight,
      ItemAcc,
      ValueAcc,
      WeightAcc) ->
    {_TailItemAcc, TailValueAcc, _TailWeightAcc} = TailRes =
        solve(T, TotalWeight, ItemAcc, ValueAcc, WeightAcc),
    {_HeadItemAcc, HeadValueAcc, _HeadWeightAcc} = HeadRes =
        solve(T,
              TotalWeight - ItemWeight,
              [ItemName | ItemAcc],
              ValueAcc + ItemValue,
              WeightAcc + ItemWeight),

    case TailValueAcc > HeadValueAcc of
        true ->
            TailRes;
        false ->
            HeadRes
    end.


/* NetRexx */
options replace format comments java crossref symbols nobinary

import java.util.List
import org.json.JSONObject
import org.json.JSONArray
import org.json.JSONTokener
import org.json.JSONException

/**
 * Using library from json.org
 *
 * @see http://www.json.org/java/index.html
 */
class RJson01 public

  properties private constant
    JSON_DWARFS = '' -
      '{\n' -
      '  "F1937_1" : {\n' -
      '    "title"  : "Snow White and the Seven Dwarfs",\n' -
      '    "year"   : 1937,\n' -
      '    "medium" : "film",\n' -
      '    "dwarfs" : [ "Grumpy", "Happy", "Sleepy", "Bashful", "Sneezy", "Dopey", "Doc" ]\n' -
      '  },\n' -
      '  "F2012_1" : {\n' -
      '    "title"  : "Mirror, Mirror",\n' -
      '    "year"   : 2012,\n' -
      '    "medium" : "film",\n' -
      '    "dwarfs" : [ "Grimm", "Butcher", "Wolf", "Napoleon", "Half Pint", "Grub", "Chuckles" ]\n' -
      '  },\n' -
      '}'

      /**
       * A bean that looks like the following JSON
       * <pre>
       * {
       *   "F2012_2" : {
       *     "title"  : "Snow White & the Huntsman",
       *     "year"   : 2012,
       *     "medium" : "film",
       *     "dwarfs" : [ "Beith", "Quert", "Muir", "Coll", "Duir", "Gus", "Gort", "Nion" ]
       *   }
       * }
       * </pre>
       */
      SAMPLE_BEAN = DwarfBean( -
        "F2012_2", -
        "Snow White & the Huntsman", -
        Long(2012), -
        "film", -
        Arrays.asList([String "Beith", "Quert", "Muir", "Coll", "Duir", "Gus", "Gort", "Nion"]) -
        )

  method main(args = String[]) public static
    say json2bean(JSON_DWARFS)
    say
    say bean2json(SAMPLE_BEAN)
    say
    return

method json2bean(dwarfs) public static returns List
    say "Make beans from this JSON string:"
    say dwarfs
    jsonBeans = ArrayList()
    do
      jd = JSONObject(JSONTokener(dwarfs))
      ns = JSONObject.getNames(jd)
      name = String
      loop name over ns
        dwarves = ArrayList()
        jn      = jd.getJSONObject(name)
        title   = jn.getString('title')
        year    = Long(jn.getLong('year'))
        medium  = jn.getString('medium')
        dwa     = jn.getJSONArray('dwarfs')
        loop di = 0 to dwa.length() - 1
          dwarves.add(dwa.getString(di))
          end di
        jb = DwarfBean(name, title, year, medium, dwarves)
        jsonBeans.add(jb.toString())
        end name
    catch ex = JSONException
      ex.printStackTrace()
    end
  return jsonBeans

method bean2json(sb = DwarfBean) public static returns String
  say "Make JSONObject from this bean:"
  say sb
  jsonString = String
  do
    jd = JSONObject(sb)
    jo = JSONObject()
    jo = jo.put(sb.keyGet(), jd)
    jsonString = jo.toString(2)
  catch ex = JSONException
    ex.printStackTrace()
  end
  return jsonString

-- =============================================================================
class RJson01.DwarfBean public binary
  properties private
    key    = String -- not part of bean
  properties indirect
    title  = String
    year   = Long
    medium = String
    dwarfs = List

  method DwarfBean(key_ = String null, title_ = String null, year_ = Long null, medium_ = String null, dwarfs_ = List null) public
    keyPut(key_)
    setTitle(title_)
    setYear(year_)
    setMedium(medium_)
    setDwarfs(dwarfs_)
    return

  method keyPut(key_ = String) public
    key = key_
    return

  method keyGet() returns String
    return key

  method toString public returns String
    ts = StringBuilder()
    ts.append(String.format("%[email protected]%08x ", [Object this.getClass().getSimpleName(), Integer(hashCode())]))
    ts.append('[')
    ts.append('key='String.valueOf(keyGet())', ')
    ts.append('title='String.valueOf(getTitle())', ')
    ts.append('year='String.valueOf(getYear())', ')
    ts.append('medium='String.valueOf(getMedium())', ')
    ts.append('dwarfs='String.valueOf(getDwarfs()))
    ts.append(']')
    return ts.toString()


>items=["map","compass","water","sandwich","glucose", ...
>  "tin","banana","apple","cheese","beer","suntan creame", ...
>  "camera","t-shirt","trousers","umbrella","waterproof trousers", ...
>  "waterproof overclothes","note-case","sunglasses", ...
>  "towel","socks","book"];
>ws = [9,13,153,50,15,68,27,39,23,52,11, ...
>  32,24,48,73,42,43,22,7,18,4,30];
>vs = [150,35,200,160,60,45,60,40,30,10,70, ...
>  30,15,10,40,70,75,80,20,12,50,10];
>A=ws_id(cols(ws));
>c=vs;
>b=[400]_ones(cols(vs),1);
>sol = intsimplex(A,b,c,eq=-1,>max,>check);
>items[nonzeros(sol)]
 map
 compass
 water
 sandwich
 glucose
 banana
 suntan creame
 waterproof trousers
 waterproof overclothes
 note-case
 sunglasses
 socks


//Solve Knapsack 0-1 using A* algorithm
//Nigel Galloway, August 3rd., 2018
let knapStar items maxW=
  let l=List.length items
  let p=System.Collections.Generic.SortedSet<float*int*float*float*list<int>>() //H*; level; value of items taken so far; weight so far
  p.Add (0.0,0,0.0,0.0,[])|>ignore
  let H items maxW=let rec H n g a=match g with |(_,w,v)::e->let t=n+w
                                                             if t<=maxW then H t e (a+v) else a+(v/w)*(maxW-n)
                                                |_->a
                   H 0.0 items 0.0
  let pAdd ((h,_,_,_,_) as n) bv=if h>bv then p.Add n |> ignore
  let fH n (bv,t) w' v' t'=let _,w,v=List.item n items
                           let e=max bv (if w<=(maxW-w') then v'+v else bv)
                           let rt=n::t'
                           if n+1<l then pAdd ((v'+H (List.skip (n+1) items) maxW),n+1,v',w',t') bv
                                         if w<=(maxW-w') then pAdd ((v'+v+H (List.skip (n+1) items) (maxW-w')),n+1,v'+v,w'+w,rt) bv
                           if e>bv then (e,rt) else (bv,t)
  let rec fN (bv,t)=
    let h,zl,zv,zw,zt as r=p.Max
    p.Remove r |> ignore
    if bv>=h then t else fN (fH zl (bv,t) zw zv zt)
  fN (fH 0 (0.0,[]) 0.0 0.0 [])


import json

var data = parseJson("""{ "foo": 1, "bar": [10, "apples"] }""")
echo data["foo"]
echo data["bar"]

var js = %* [{"name": "John", "age": 30}, {"name": "Susan", "age": 31}]
echo js


use Struct;
use JSON;

bundle Default {
  class Json {
    function : Main(args : String[]) ~ Nil {
      parser := JSONParser->New("{ \"foo\": 1, \"bar\": [10, \"apples\"] }");
      root := parser->Parse();
      if(root <> Nil) {
        root->ToString()->PrintLine();
      };
    }
  }
}


NSString *jsonString = @"{ \"foo\": 1, \"bar\": [10, \"apples\"] }";
id obj = [NSJSONSerialization
    JSONObjectWithData: [jsonString dataUsingEncoding: NSUTF8StringEncoding]
               options: 0
                 error: NULL];
NSLog(@"%@", obj);

NSDictionary *dict = @{ @"blue": @[@1, @2], @"ocean": @"water"};
NSData *jsonData = [NSJSONSerialization dataWithJSONObject: dict
                                                   options: 0
                                                     error: NULL];
NSString *jsonString2 = [[NSString alloc] initWithData: jsonData
                                              encoding: NSUTF8StringEncoding];
NSLog(@"%@", jsonString2);


USING: accessors arrays fry io kernel locals make math
math.order math.parser math.ranges sequences sorting ;
IN: rosetta.knappsack.0-1

TUPLE: item
    name weight value ;

CONSTANT: items {
        T{ item f "map" 9 150 }
        T{ item f "compass" 13 35 }
        T{ item f "water" 153 200 }
        T{ item f "sandwich" 50 160 }
        T{ item f "glucose" 15 60 }
        T{ item f "tin" 68 45 }
        T{ item f "banana" 27 60 }
        T{ item f "apple" 39 40 }
        T{ item f "cheese" 23 30 }
        T{ item f "beer" 52 10 }
        T{ item f "suntan cream" 11 70 }
        T{ item f "camera" 32 30 }
        T{ item f "t-shirt" 24 15 }
        T{ item f "trousers" 48 10 }
        T{ item f "umbrella" 73 40 }
        T{ item f "waterproof trousers" 42 70 }
        T{ item f "waterproof overclothes" 43 75 }
        T{ item f "note-case" 22 80 }
        T{ item f "sunglasses" 7 20 }
        T{ item f "towel" 18 12 }
        T{ item f "socks" 4 50 }
        T{ item f "book" 30 10 }
    }

CONSTANT: limit 400

: make-table ( -- table )
    items length 1 + [ limit 1 + 0 <array> ] replicate ;

:: iterate ( item-no table -- )
    item-no table nth :> prev
    item-no 1 + table nth :> curr
    item-no items nth :> item
    limit [1,b] [| weight |
        weight prev nth
        weight item weight>> - dup 0 >=
        [ prev nth item value>> + max ]
        [ drop ] if
        weight curr set-nth
    ] each ;

: fill-table ( table -- )
    [ items length iota ] dip
    '[ _ iterate ] each ;

:: extract-packed-items ( table -- items )
    [
        limit :> weight!
        items length iota <reversed> [| item-no |
            item-no table nth :> prev
            item-no 1 + table nth :> curr
            weight [ curr nth ] [ prev nth ] bi =
            [
                item-no items nth
                [ name>> , ] [ weight>> weight swap - weight! ] bi
            ] unless
        ] each
    ] { } make ;

: solve-knappsack ( -- items value )
    make-table [ fill-table ]
    [ extract-packed-items ] [ last last ] tri ;

: main ( -- )
    solve-knappsack
    "Total value: " write number>string print
    "Items packed: " print
    natural-sort
    [ "   " write print ] each ;


\ Rosetta Code Knapp-sack 0-1 problem.  Tested under GForth 0.7.3.
\ 22 items. On current processors a set fits nicely in one CELL (32 or 64 bits).
\ Brute force approach: for every possible set of 22 items,
\ check for admissible solution then for optimal set.

: offs HERE over - ;
        400 VALUE WLIMIT
        0 VALUE ITEM
        0 VALUE VAL
        0 VALUE /ITEM
        0 VALUE ITEMS#
Create Sack
HERE
        9 ,                     offs TO VAL
        150 ,                   offs TO ITEM
        s" map            " s,  offs TO /ITEM
DROP
 13 ,  35 , s" compass        " s,
153 , 200 , s" water          " s,
 50 , 160 , s" sandwich       " s,
 15 ,  60 , s" glucose        " s,
 68 ,  45 , s" tin            " s,
 27 ,  60 , s" banana         " s,
 39 ,  40 , s" apple          " s,
 23 ,  30 , s" cheese         " s,
 52 ,  10 , s" beer           " s,
 11 ,  70 , s" suntan cream   " s,
 32 ,  30 , s" camera         " s,
 24 ,  15 , s" T-shirt        " s,
 48 ,  10 , s" trousers       " s,
 73 ,  40 , s" umbrella       " s,
 42 ,  70 , s" wp trousers    " s,
 43 ,  75 , s" wp overclothes " s,
 22 ,  80 , s" note-case      " s,
  7 ,  20 , s" sunglasses     " s,
 18 ,  12 , s" towel          " s,
  4 ,  50 , s" socks          " s,
 30 ,  10 , s" book           " s,
        HERE VALUE END-SACK
        VARIABLE Sol            \ Solution  Set
        VARIABLE Vmax           \ Temporary Maximum Value
        VARIABLE Sum            \ Temporary Sum (for speed-up)
: ]sum          ( Rtime: set -- sum  ;Ctime: hilimit.a start.a -- )
\ Loop unwinding & precomputing addresses
        ]
        ]] Sum OFF [[
        DO              ]] dup [[  1  ]] LITERAL AND IF [[  I  ]] LITERAL @ Sum +! THEN 2/ [[
        /ITEM +LOOP     ]] drop Sum @ [[
; IMMEDIATE
: solve         ( -- )
        Vmax OFF
        [ 1 END-SACK Sack - /ITEM / lshift 1- ]L 0
        DO
                I [ END-SACK Sack ]sum ( by weight ) WLIMIT <
                IF
                        I [ END-SACK VAL + Sack VAL + ]sum ( by value )
                        dup Vmax @ >
                        IF  Vmax ! I Sol !  ELSE  drop  THEN
                THEN
        LOOP
;
: .solution     ( -- )
        Sol @ END-SACK ITEM + Sack ITEM +
        DO
                dup 1 AND  IF  I count type cr  THEN
                2/
        /ITEM +LOOP
        drop
        ." Weight: " Sol @ [ END-SACK Sack ]sum .  ."  Value: " Sol @ [ END-SACK VAL + Sack VAL + ]sum .
;


type json item =
  < name    "Name": string;
    kingdom "Kingdom": string;
    phylum  "Phylum": string;
    class_  "Class": string;
    order   "Order": string;
    family  "Family": string;
    tribe   "Tribe": string
  >

let str = "
  {
    \"Name\":    \"camel\",
    \"Kingdom\": \"Animalia\",
    \"Phylum\":  \"Chordata\",
    \"Class\":   \"Mammalia\",
    \"Order\":   \"Artiodactyla\",
    \"Family\":  \"Camelidae\",
    \"Tribe\":   \"Camelini\"
  }"

let () =
  let j = Json_io.json_of_string str in
  print_endline (Json_io.string_of_json j);


>{"parents":["Otmar Gutmann", "Silvio Mazzola"], "name":"Pingu", "born":1986} .s
[1] (Json) {"parents" : ["Otmar Gutmann", "Silvio Mazzola"], "name" : "Pingu", "born" : 1986 }
ok
>asString .s
[1] (String) {"parents" : ["Otmar Gutmann", "Silvio Mazzola"], "name" : "Pingu", "born" :1986 }
ok
>perform .s
[1] (Json) {"parents" : ["Otmar Gutmann", "Silvio Mazzola"], "name" : "Pingu", "born" : 1986 }
ok
>


(import (file json))

(define o (read-json-string "
  {
    'name': 'John',
    'full name': 'John Smith',
    'age': 42,
    'weight': 156.18,
    'married': false,
    'address': {
      'street': '21 2nd Street',
      'city': 'New York',
    },
    'additional staff': [
      {
        'type': 'numbers',
        'numbers': [ 1, -2, 0.75, -4.567 ]
      },
      {
        'type': 'phone',
        'number': '222 222-2222'
      }
    ]
  }"))
(print o)

(print-json-with display o)
(print-json-with display {
  'name "John"
  '|full name| "John Smith"
  'age 42
  'married #false
  'address {
    'street "21 2nd Street"
    'city   "New York"
  }
  '|additional staff| [
    {
      'type "numbers"
      'numbers [ 1 2 3 4 ]
    }
    {
      'type "phone"
      'number "222 222-2222"
    }
  ]


#define Tabu = Chr(9)
Dim As Integer i, A, P, V, N
Dim As Integer MejorArticulo, MejorValor = 0
Type Knapsack
    articulo As String*22
    peso As Integer
    valor As Integer
End Type
Dim item(1 To 22) As Knapsack => { _
("map                   ",   9, 150), ("compass               ",  13,  35), _
("water                 ", 153, 200), ("sandwich              ",  50, 160), _
("glucose               ",  15,  60), ("tin                   ",  68,  45), _
("banana                ",  27,  60), ("apple                 ",  39,  40), _
("cheese                ",  23,  30), ("beer                  ",  52,  10), _
("suntan cream          ",  11,  70), ("camera                ",  32,  30), _
("T-shirt               ",  24,  15), ("trousers              ",  48,  10), _
("umbrella              ",  73,  40), ("waterproof trousers   ",  42,  70), _
("waterproof overclothes",  43,  75), ("note-case             ",  22,  80), _
("sunglasses            ",   7,  20), ("towel                 ",  18,  12), _
("socks                 ",   4,  50), ("book                  ",  30,  10)}

For i = 1 To (1 Shl 22)-1
    A = i : P = 0 : V = 0 : N = 1
    While A
        If A And 1 Then
            P += item(N).peso
            V += item(N).valor
        End If
        A Shr= 1
        N += 1
    Wend
    If V > MejorValor  And  P <= 400 Then
        MejorValor = V
        MejorArticulo = i
    End If
Next

A = MejorArticulo : P = 0 : V = 0 : N = 1
While A
    If A And 1 Then
        Print "  "; item(N).articulo; Tabu;
        Print item(N).peso; Tabu; item(N).valor
        P += item(N).peso
        V += item(N).valor
    End If
    A Shr= 1 : N += 1
Wend
Print "Totals:"; Spc(25); P; Tabu; V
Sleep


/* using a longchar to read and write to, can also be file, memptr, stream */
DEFINE VARIABLE lcjson AS LONGCHAR NO-UNDO.

/* temp-table defines object, can also be dataset */
DEFINE TEMP-TABLE example
   FIELD blue  AS INTEGER EXTENT 2
   FIELD ocean AS CHARACTER
   .
CREATE example.
ASSIGN
   example.blue [1]  =  1
   example.blue [2]  =  2
   example.ocean     =  "water"
   .
/* write-json to put result in lcjson, true indicates formatted */
TEMP-TABLE example:DEFAULT-BUFFER-HANDLE:WRITE-JSON( "LONGCHAR", lcjson, TRUE ).

/* display result */
MESSAGE
   STRING( lcjson )
VIEW-AS ALERT-BOX.

/* empty results */
EMPTY TEMP-TABLE example.

/* read-json to get result from lcjson */
TEMP-TABLE example:DEFAULT-BUFFER-HANDLE:READ-JSON( "LONGCHAR", lcjson ).

FIND example.
/* display results */
MESSAGE
   example.blue [1] example.blue [2] SKIP
   example.ocean
VIEW-AS ALERT-BOX.


declare
  [JSON] = {Module.link ['JSON.ozf']}

  {System.show {JSON.decode "{ \"foo\": 1, \"bar\": [10, \"apples\"] }"}}

  Sample = object(blue:array(1 2) ocean:"water")
  {System.showInfo {JSON.encode Sample}}


use JSON;

my $data = decode_json('{ "foo": 1, "bar": [10, "apples"] }');

my $sample = { blue => [1,2], ocean => "water" };
my $json_string = encode_json($sample);


window 1, @"Knapsack Problem", (0,0,480,270)

_maxWeight = 400

void local fn FillKnapsack
  long              totalWeight = 0, totalValue = 0, itemWeight, unusedWeight
  CFDictionaryRef   item, extraItem = NULL
  SortDescriptorRef sd
  CFMutableArrayRef packedItems

  CFArrayRef items = @[
  @{@"item":@"map",                    @"weight":@9,   @"value":@150},
  @{@"item":@"compass",                @"weight":@13,  @"value":@35 },
  @{@"item":@"water",                  @"weight":@153, @"value":@200},
  @{@"item":@"sandwich",               @"weight":@50,  @"value":@160},
  @{@"item":@"glucose",                @"weight":@15,  @"value":@60 },
  @{@"item":@"tin",                    @"weight":@68,  @"value":@45 },
  @{@"item":@"banana",                 @"weight":@27,  @"value":@60 },
  @{@"item":@"apple",                  @"weight":@39,  @"value":@40 },
  @{@"item":@"cheese",                 @"weight":@23,  @"value":@30 },
  @{@"item":@"beer",                   @"weight":@52,  @"value":@10 },
  @{@"item":@"suntan cream",           @"weight":@11,  @"value":@70 },
  @{@"item":@"camera",                 @"weight":@32,  @"value":@30 },
  @{@"item":@"T-shirt",                @"weight":@24,  @"value":@15 },
  @{@"item":@"trousers",               @"weight":@48,  @"value":@10 },
  @{@"item":@"umbrella",               @"weight":@73,  @"value":@40 },
  @{@"item":@"waterproof trousers",    @"weight":@42,  @"value":@70 },
  @{@"item":@"waterproof overclothes", @"weight":@43,  @"value":@75 },
  @{@"item":@"note-case",              @"weight":@22,  @"value":@80 },
  @{@"item":@"sunglasses",             @"weight":@7,   @"value":@20 },
  @{@"item":@"towel",                  @"weight":@18,  @"value":@12 },
  @{@"item":@"socks",                  @"weight":@4,   @"value":@50 },
  @{@"item":@"book",                   @"weight":@30,  @"value":@10 }
  ]

  sd = fn SortDescriptorWithKey( @"value", NO )
  items = fn ArraySortedArrayUsingDescriptors( items, @[sd] )
  packedItems = fn MutableArrayWithCapacity(0)
  for item in items
    itemWeight = fn NumberIntegerValue(item[@"weight"])
    if ( totalWeight + itemWeight <= _maxWeight )
      MutableArrayAddObject( packedItems, item )
      totalWeight += itemWeight
      totalValue += fn NumberIntegerValue(item[@"value"])
    end if
  next

  text @"Menlo-Bold",,, fn ColorWithRGB(1.0,0.0,1.0,0.25),, 170
  print @"Item",@"Weight",@"Value"
  text @"Menlo",,, fn ColorClear
  for item in packedItems
    printf @"%@\t%6ld\t%5ld",item[@"item"],fn NumberIntegerValue(item[@"weight"]),fn NumberIntegerValue(item[@"value"])
  next
  text ,,, fn ColorWithRGB(1.0,0.0,1.0,0.25)
  printf @"knapsack\t%6ld\t%5ld",totalWeight,totalValue

  text
  print

  unusedWeight = _maxWeight - totalWeight

  for item in items
    if ( fn NumberIntegerValue(item[@"weight"]) <= unusedWeight )
      extraItem = item : break
    end if
  next

  if ( extraItem ) then printf @"There's just enough room for extra %@!", extraItem[@"item"]
end fn

fn FillKnapsack

HandleEvents


package main

import "fmt"

type item struct {
    string
    w, v int
}

var wants = []item{
    {"map", 9, 150},
    {"compass", 13, 35},
    {"water", 153, 200},
    {"sandwich", 50, 160},
    {"glucose", 15, 60},
    {"tin", 68, 45},
    {"banana", 27, 60},
    {"apple", 39, 40},
    {"cheese", 23, 30},
    {"beer", 52, 10},
    {"suntan cream", 11, 70},
    {"camera", 32, 30},
    {"T-shirt", 24, 15},
    {"trousers", 48, 10},
    {"umbrella", 73, 40},
    {"waterproof trousers", 42, 70},
    {"waterproof overclothes", 43, 75},
    {"note-case", 22, 80},
    {"sunglasses", 7, 20},
    {"towel", 18, 12},
    {"socks", 4, 50},
    {"book", 30, 10},
}

const maxWt = 400

func main() {
    items, w, v := m(len(wants)-1, maxWt)
    fmt.Println(items)
    fmt.Println("weight:", w)
    fmt.Println("value:", v)
}

func m(i, w int) ([]string, int, int) {
    if i < 0 || w == 0 {
        return nil, 0, 0
    } else if wants[i].w > w {
        return m(i-1, w)
    }
    i0, w0, v0 := m(i-1, w)
    i1, w1, v1 := m(i-1, w-wants[i].w)
    v1 += wants[i].v
    if v1 > v0 {
        return append(i1, wants[i].string), w1 + wants[i].w, v1
    }
    return i0, w0, v0
}


-- demo\rosetta\JSON.exw
with javascript_semantics
include builtins/json.e

puts(1,"roundtrip (10 examples):\n")
sequence json_strings = {`{"this":"that","age":{"this":"that","age":29}}`,
                         `1`,
                         `"hello"`,
                         `null`,
                         `[12]`,
                         `[null,12]`,
                         `[]`,
                         `{"this":"that","age":29}`,
                         `{}`,
                         `[null,[null,12]]`}

for i=1 to length(json_strings) do
    string s = json_strings[i]
    puts(1,s&"\n")
    object json_object = parse_json(s)
    puts(1,print_json("",json_object,true)&"\n")
    if not equal(print_json("",json_object,true),s) then ?9/0 end if
end for


<?php
$data = json_decode('{ "foo": 1, "bar": [10, "apples"] }'); // dictionaries will be returned as objects
$data2 = json_decode('{ "foo": 1, "bar": [10, "apples"] }', true); // dictionaries will be returned as arrays

$sample = array( "blue" => array(1,2), "ocean" => "water" );
$json_string = json_encode($sample);
?>


def totalWeight = { list -> list*.weight.sum() }
def totalValue = { list -> list*.value.sum() }

def knapsack01bf = { possibleItems ->
    possibleItems.subsequences().findAll{ ss ->
        def w = totalWeight(ss)
        350 < w && w < 401
    }.max(totalValue)
}


inv = [("map",9,150), ("compass",13,35), ("water",153,200), ("sandwich",50,160),
	("glucose",15,60), ("tin",68,45), ("banana",27,60), ("apple",39,40),
	("cheese",23,30), ("beer",52,10), ("cream",11,70), ("camera",32,30),
	("tshirt",24,15), ("trousers",48,10), ("umbrella",73,40), ("trousers",42,70),
	("overclothes",43,75), ("notecase",22,80), ("sunglasses",7,20), ("towel",18,12),
	("socks",4,50), ("book",30,10)]

-- get all combos of items under total weight sum; returns value sum and list
combs [] _ = [ (0, []) ]
combs ((name,w,v):rest) cap = combs rest cap ++
		      if w > cap then [] else map (prepend (name,w,v)) (combs rest (cap - w))
		      	where prepend (name,w,v) (v2, lst) = (v2 + v, (name,w,v):lst)

main = do
	putStr "Total value: "; print value
	mapM_ print items
		where (value, items) = maximum $ combs inv 400


(de checkJson (X Item)
   (unless (= X Item)
      (quit "Bad JSON" Item) ) )

(de readJson ()
   (case (read "_")
      ("{"
         (make
            (for (X (readJson)  (not (= "}" X))  (readJson))
               (checkJson ":" (readJson))
               (link (cons X (readJson)))
               (T (= "}" (setq X (readJson))))
               (checkJson "," X) ) ) )
      ("["
         (make
            (link T)  # Array marker
            (for (X (readJson)  (not (= "]" X))  (readJson))
               (link X)
               (T (= "]" (setq X (readJson))))
               (checkJson "," X) ) ) )
      (T
         (let X @
            (cond
               ((pair X) (pack X))
               ((and (= "-" X) (format (peek)))
                  (- (read)) )
               (T X) ) ) ) ) )

(de printJson (Item)  # For simplicity, without indentation
   (cond
      ((atom Item) (if Item (print @) (prin "{}")))
      ((=T (car Item))
         (prin "[")
         (map
            '((X)
               (printJson (car X))
               (and (cdr X) (prin ", ")) )
            (cdr Item) )
         (prin "]") )
      (T
         (prin "{")
         (map
            '((X)
               (print (caar X))
               (prin ": ")
               (printJson (cdar X))
               (and (cdr X) (prin ", ")) )
            Item )
         (prin "}") ) ) )


int main() {
	// Decoding
	string json = "{\"cake\":[\"desu\",1,2.3],\"foo\":1}";
	write("%O\n", Standards.JSON.decode(json));

	// Encoding
	mapping m = ([
		"foo": ({ 1, 2, 3 }),
		"bar": "hello"
	]);

	write("%s\n", Standards.JSON.encode(m));
}


# JSON input is being stored in ordered hashtable.
# Ordered hashtable is available in PowerShell v3 and higher.
[ordered]@{ "foo"= 1; "bar"= 10, "apples" } | ConvertTo-Json

# ConvertFrom-Json converts a JSON-formatted string to a custom object.
# If you use the Invoke-RestMethod cmdlet there is not need for the ConvertFrom-Json cmdlet
Invoke-WebRequest -Uri "http://date.jsontest.com" | ConvertFrom-Json


link printf

global wants                    # items wanted for knapsack

procedure main(A) # kanpsack 0-1
   if !A == ("--trace"|"-t") then &trace := -1     # trace everything (debug)
   if !A == ("--memoize"|"-m") then m :=: Memo_m   # hook (swap) procedure

   printf("Knapsack-0-1: with maximum weight allowed=%d.\n",maxw  := 400)
   showwanted(wants := get_wants())
   showcontents(bag := m(*wants,maxw))
   printf("Performance: time=%d ms collections=%d\n",&time,&collections)
end

record packing(items,weight,value)

procedure Memo_m(i,w)           #: Hook procedure to memoize the knapsack
static memoT
initial memoT := table()
   return \memoT[k := i||","||w] | ( memoT[k] := Memo_m(i,w) )
end

procedure m(i,w)                #: Solve the Knapsack 0-1 as per Wikipedia
static nil
initial nil := packing([],0,0)
   if 0 = (i | w) then
      return nil
   else if wants[i].weight > w then
           return m(i-1, w)
        else {
            x0 := m(i-1,w)
            x1 := m(i-1,w-wants[i].weight)
            if ( x1.value + wants[i].value) > x0.value then
               return packing(x1.items ||| wants[i].items,
                              x1.weight + wants[i].weight,
                              x1.value + wants[i].value)
            else
               return x0
        }
end

procedure showwanted(wants)     #: show the list of wanted items
   every (tw := 0) +:= (!wants).weight
   printf("Packing list has total weight=%d and includes %d items [",tw,*wants)
   every printf(" %s",!(!wants).items|"]\n")
end

procedure showcontents(bag)     #: show the list of the packed bag
   printf("The bag weighs=%d holding %d items [",bag.weight,*bag.items)
   every printf(" %s",!bag.items|"]\n")
end

procedure get_wants()           #: setup list of wanted items
   return  [ packing(["map"], 9, 150),
             packing(["compass"], 13, 35),
             packing(["water"], 153, 200),
             packing(["sandwich"], 50, 160),
             packing(["glucose"], 15, 60),
             packing(["tin"], 68, 45),
             packing(["banana"], 27, 60),
             packing(["apple"], 39, 40),
             packing(["cheese"], 23, 30),
             packing(["beer"], 52, 10),
             packing(["suntan cream"], 11, 70),
             packing(["camera"], 32, 30),
             packing(["T-shirt"], 24, 15),
             packing(["trousers"], 48, 10),
             packing(["umbrella"], 73, 40),
             packing(["waterproof trousers"], 42, 70),
             packing(["waterproof overclothes"], 43, 75),
             packing(["note-case"], 22, 80),
             packing(["sunglasses"], 7, 20),
             packing(["towel"], 18, 12),
             packing(["socks"], 4, 50),
             packing(["book"], 30, 10) ]
end


:- use_module([ library(http/json),
                library(func) ]).

test_json('{"widget": { "debug": "on", "window": { "title": "Sample Konfabulator Widget", "name": "main_window", "width": 500, "height": 500 }, "image": { "src": "Images/Sun.png", "name": "sun1", "hOffset": 250, "vOffset": 250, "alignment": "center" }, "text": { "data": "Click Here", "size": 36, "style": "bold", "name": "text1", "hOffset": 250, "vOffset": 100, "alignment": "center", "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" }}}').

reading_JSON_term :-
    atom_json_dict(test_json(~), Dict, []), %% This accomplishes reading in the JSON data
    writeln( 'JSON as Prolog dict: ~w~n'
           $ Dict),
    writeln( 'Access field "widget.text.data": ~s~n'
           $ Dict.widget.text.data),
    writeln( 'Alter field "widget": ~w~n'
           $ Dict.put(widget, "Altered")).

searalize_a_JSON_term :-
    Dict = _{book:_{title:"To Mock a Mocking Bird",
                    author:_{first_name:"Ramond",
                             last_name:"Smullyan"},
                    publisher:"Alfred A. Knopf",
                    year:1985
                   }},
    json_write(current_output, Dict). %% This accomplishes serializing the JSON object.


OpenConsole()
If CreateJSON(1)
  PB_Team_Members=SetJSONObject(JSONValue(1))
  SetJSONString(AddJSONMember(PB_Team_Members,"PB_Team_Member_1"),"Frederic Laboureur")
  SetJSONString(AddJSONMember(PB_Team_Members,"PB_Team_Member_2"),"Andre Beer")
  SetJSONString(AddJSONMember(PB_Team_Members,"PB_Team_Member_3"),"Timo Harter")
EndIf

If CreateJSON(2)
  Former_Team_Members=SetJSONArray(JSONValue(2))
  SetJSONString(AddJSONElement(Former_Team_Members),"Richard Andersson")
  SetJSONString(AddJSONElement(Former_Team_Members),"Benny Sels")
  SetJSONString(AddJSONElement(Former_Team_Members),"Danilo Krahn")
EndIf

PrintN("PureBasic - Team Members:")
PrintN(ComposeJSON(1,#PB_JSON_PrettyPrint)+#CRLF$)
PrintN("PureBasic - Former Team Members:")
PrintN(ComposeJSON(2,#PB_JSON_PrettyPrint)+#CRLF$)

#DL=Chr(34)
PB_Special_thanks$="[ " +#DL+"Gary Willoughby"+#DL+", " +#DL+"Mark James"+#DL+", " +#DL+"Neil Hodgson"+#DL+" ]"
NewList otherpersons.s()

If ParseJSON(3,PB_Special_thanks$)
  ExtractJSONList(JSONValue(3),otherpersons())
  PrintN("Pure Basic - and others:")
  ForEach otherpersons() : PrintN(otherpersons()) : Next
Else
  PrintN(JSONErrorMessage() + " : " + Str(JSONErrorPosition()))
  PrintN(Left(PB_Special_thanks$,JSONErrorPosition()))
  PrintN(Mid(PB_Special_thanks$,JSONErrorPosition()+1))
EndIf
Input()


>>> import json
>>> data = json.loads('{ "foo": 1, "bar": [10, "apples"] }')
>>> sample = { "blue": [1,2], "ocean": "water" }
>>> json_string = json.dumps(sample)
>>> json_string
'{"blue": [1, 2], "ocean": "water"}'
>>> sample
{'blue': [1, 2], 'ocean': 'water'}
>>> data
{'foo': 1, 'bar': [10, 'apples']}


library(rjson)
data <- fromJSON('{ "foo": 1, "bar": [10, "apples"] }')
data


#lang racket

(require json)

(string->jsexpr
 "{\"foo\":[1,2,3],\"bar\":null,\"baz\":\"blah\"}")

(write-json '(1 2 "three" #hash((x . 1) (y . 2) (z . 3))))


use JSON::Tiny;

my $data = from-json('{ "foo": 1, "bar": [10, "apples"] }');

my $sample = { blue => [1,2], ocean => "water" };
my $json_string = to-json($sample);


package hu.pj.alg.test;

import hu.pj.alg.ZeroOneKnapsack;
import hu.pj.obj.Item;
import java.util.*;
import java.text.*;

public class ZeroOneKnapsackForTourists {

    public ZeroOneKnapsackForTourists() {
        ZeroOneKnapsack zok = new ZeroOneKnapsack(400); // 400 dkg = 400 dag = 4 kg

        // making the list of items that you want to bring
        zok.add("map", 9, 150);
        zok.add("compass", 13, 35);
        zok.add("water", 153, 200);
        zok.add("sandwich", 50, 160);
        zok.add("glucose", 15, 60);
        zok.add("tin", 68, 45);
        zok.add("banana", 27, 60);
        zok.add("apple", 39, 40);
        zok.add("cheese", 23, 30);
        zok.add("beer", 52, 10);
        zok.add("suntan cream", 11, 70);
        zok.add("camera", 32, 30);
        zok.add("t-shirt", 24, 15);
        zok.add("trousers", 48, 10);
        zok.add("umbrella", 73, 40);
        zok.add("waterproof trousers", 42, 70);
        zok.add("waterproof overclothes", 43, 75);
        zok.add("note-case", 22, 80);
        zok.add("sunglasses", 7, 20);
        zok.add("towel", 18, 12);
        zok.add("socks", 4, 50);
        zok.add("book", 30, 10);

        // calculate the solution:
        List<Item> itemList = zok.calcSolution();

        // write out the solution in the standard output
        if (zok.isCalculated()) {
            NumberFormat nf  = NumberFormat.getInstance();

            System.out.println(
                "Maximal weight           = " +
                nf.format(zok.getMaxWeight() / 100.0) + " kg"
            );
            System.out.println(
                "Total weight of solution = " +
                nf.format(zok.getSolutionWeight() / 100.0) + " kg"
            );
            System.out.println(
                "Total value              = " +
                zok.getProfit()
            );
            System.out.println();
            System.out.println(
                "You can carry the following materials " +
                "in the knapsack:"
            );
            for (Item item : itemList) {
                if (item.getInKnapsack() == 1) {
                    System.out.format(
                        "%1$-23s %2$-3s %3$-5s %4$-15s \n",
                        item.getName(),
                        item.getWeight(), "dag  ",
                        "(value = " + item.getValue() + ")"
                    );
                }
            }
        } else {
            System.out.println(
                "The problem is not solved. " +
                "Maybe you gave wrong data."
            );
        }

    }

    public static void main(String[] args) {
        new ZeroOneKnapsackForTourists();
    }

} // class


json-str: {{"menu": {
    "id": "file",
    "string": "File:",
    "number": -3,
    "boolean": true,
    "boolean2": false,
    "null": null,
    "array": [1, 0.13, null, true, false, "\t\r\n"],
    "empty-string": ""
  }
}}

res: json-to-rebol json-str
js: rebol-to-json res


require 'json'

ruby_obj = JSON.parse('{"blue": [1, 2], "ocean": "water"}')
puts ruby_obj

ruby_obj["ocean"] = { "water" => ["fishy", "salty"] }
puts JSON.generate(ruby_obj)
puts JSON.pretty_generate(ruby_obj)


[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"


scala> import scala.util.parsing.json.{JSON, JSONObject}
import scala.util.parsing.json.{JSON, JSONObject}

scala> JSON.parseFull("""{"foo": "bar"}""")
res0: Option[Any] = Some(Map(foo -> bar))

scala> JSONObject(Map("foo" -> "bar")).toString()
res1: String = {"foo" : "bar"}


/*global portviz:false, _:false */
/*
 * 0-1 knapsack solution, recursive, memoized, approximate.
 *
 * credits:
 *
 * the Go implementation here:
 *   http://rosettacode.org/mw/index.php?title=Knapsack_problem/0-1
 *
 * approximation details here:
 *   http://math.mit.edu/~goemans/18434S06/knapsack-katherine.pdf
 */
portviz.knapsack = {};
(function() {
  this.combiner = function(items, weightfn, valuefn) {
    // approximation guarantees result >= (1-e) * optimal
    var _epsilon = 0.01;
    var _p = _.max(_.map(items,valuefn));
    var _k = _epsilon * _p / items.length;

    var _memo = (function(){
      var _mem = {};
      var _key = function(i, w) {
        return i + '::' + w;
      };
      return {
        get: function(i, w) {
          return _mem[_key(i,w)];
        },
        put: function(i, w, r) {
          _mem[_key(i,w)]=r;
          return r;
        }
      };
    })();

    var _m = function(i, w) {

      i = Math.round(i);
      w = Math.round(w);

      if (i < 0 || w === 0) {
        // empty base case
        return {items: [], totalWeight: 0, totalValue: 0};
      }

      var mm = _memo.get(i,w);
      if (!_.isUndefined(mm)) {
        return mm;
      }

      var item = items[i];
      if (weightfn(item) > w) {
        //item does not fit, try the next item
        return _memo.put(i, w, _m(i-1, w));
      }
      // this item could fit.
      // are we better off excluding it?
      var excluded = _m(i-1, w);
      // or including it?
      var included = _m(i-1, w - weightfn(item));
      if (included.totalValue + Math.floor(valuefn(item)/_k) > excluded.totalValue) {
        // better off including it
        // make a copy of the list
        var i1 = included.items.slice();
        i1.push(item);
        return _memo.put(i, w,
          {items: i1,
           totalWeight: included.totalWeight + weightfn(item),
           totalValue: included.totalValue + Math.floor(valuefn(item)/_k)});
      }
      //better off excluding it
      return _memo.put(i,w, excluded);
    };
    return {
      /* one point */
      one: function(maxweight) {
        var scaled = _m(items.length - 1, maxweight);
        return {
          items: scaled.items,
          totalWeight: scaled.totalWeight,
          totalValue: scaled.totalValue * _k
        };
      },
      /* the entire EF */
      ef: function(maxweight, step) {
        return _.map(_.range(0, maxweight+1, step), function(weight) {
          var scaled = _m(items.length - 1, weight);
          return {
            items: scaled.items,
            totalWeight: scaled.totalWeight,
            totalValue: scaled.totalValue * _k
          };
        });
      }
    };
  };
}).apply(portviz.knapsack);

/*global portviz:false, _:false */
/*
 * after rosettacode.org/mw/index.php?title=Knapsack_problem/0-1
 */
var allwants = [
  {name:"map", weight:9, value: 150},
  {name:"compass", weight:13, value: 35},
  {name:"water", weight:153, value: 200},
  {name:"sandwich", weight: 50, value: 160},
  {name:"glucose", weight:15, value: 60},
  {name:"tin", weight:68, value: 45},
  {name:"banana", weight:27, value: 60},
  {name:"apple", weight:39, value: 40},
  {name:"cheese", weight:23, value: 30},
  {name:"beer", weight:52, value: 10},
  {name:"suntan cream", weight:11, value: 70},
  {name:"camera", weight:32, value: 30},
  {name:"T-shirt", weight:24, value: 15},
  {name:"trousers", weight:48, value: 10},
  {name:"umbrella", weight:73, value: 40},
  {name:"waterproof trousers", weight:42, value: 70},
  {name:"waterproof overclothes", weight:43, value: 75},
  {name:"note-case", weight:22, value: 80},
  {name:"sunglasses", weight:7, value: 20},
  {name:"towel", weight:18, value: 12},
  {name:"socks", weight:4, value: 50},
  {name:"book", weight:30, value: 10}
];

var near = function(actual, expected, tolerance) {
  if (expected === 0 && actual === 0) return true;
  if (expected === 0) {
    return Math.abs(expected - actual) / actual < tolerance;
  }
  return Math.abs(expected - actual) / expected < tolerance;
};

test("one knapsack", function() {
  var combiner =
    portviz.knapsack.combiner(allwants,
      function(x){return x.weight;},
      function(x){return x.value;});
  var oneport = combiner.one(400);
  ok(near(oneport.totalValue, 1030, 0.01), "correct total value");
  ok(near(oneport.totalValue, 1030, 0.01), "correct total value");
  equal(oneport.totalWeight, 396, "correct total weight");
});

test("frontier", function() {
  var combiner =
    portviz.knapsack.combiner(allwants,
      function(x){return x.weight;},
      function(x){return x.value;});
  var ef = combiner.ef(400, 1);
  equal(ef.length, 401, "401 because it includes the endpoints");
  ef = combiner.ef(400, 40);
  equal(ef.length, 11, "11 because it includes the endpoints");
  var expectedTotalValue = [
    0,
    330,
    445,
    590,
    685,
    755,
    810,
    860,
    902,
    960,
    1030
  ] ;
  _.each(ef, function(element, index) {
    // 15% error!  bleah!
    ok(near(element.totalValue, expectedTotalValue[index], 0.15),
      'actual ' + element.totalValue + ' expected ' + expectedTotalValue[index]);
  });
  deepEqual(_.pluck(ef, 'totalWeight'), [
    0,
    39,
    74,
    118,
    158,
    200,
    236,
    266,
    316,
    354,
    396
  ]);
  deepEqual(_.map(ef, function(x){return x.items.length;}), [
    0,
    4,
    6,
    7,
    9,
    10,
    10,
    12,
    14,
    11,
    12
   ]);
});


(use json)
(define object-example
  (with-input-from-string "{\"foo\": \"bar\", \"baz\": [1, 2, 3]}"
                          json-read))
(pp object-example)
; this prints #(("foo" . "bar") ("baz" 1 2 3))

(json-write #([foo . bar]
              [baz   1 2 3]
              [qux . #((rosetta . code))]))
; this writes the following:
; {"foo": "bar", "baz": [1, 2, 3], "qux": {"foo": "bar"}}


set jsonString to <<{"foo": 10, "bar": [1, 2, 3]}>>
put JSONValue(jsonString)

set dataObject to (string_value: "lorem ipsum", int_value: 314, array_value: (2, 4, 6))
put JSONFormat(dataObject)


var json = require('JSON').new;
var data = json.decode('{"blue": [1, 2], "ocean": "water"}');
say data;
data{:ocean} = Hash.new(water => %w[fishy salty]);
say json.encode(data);


NeoJSONReader fromString: '{ "foo": 1, "bar": [10, "apples"] }'.


# Input should be the array of objects giving name, weight and value.
# Because of the way addition is defined on null and because of the
# way setpath works, there is no need to initialize the matrix m in
# detail.
def dynamic_knapsack(W):
  . as $objects
  | length as $n
  | reduce range(1; $n+1) as $i                           # i is the number of items
      # state: m[i][j] is an array of [value, array_of_object_names]
      (null;                           # see above remark about initialization of m
       $objects[$i-1] as $o
       | reduce range(0; W+1) as $j
           ( .;
             if $o.weight <= $j then
               .[$i-1][$j][0] as $v1                               # option 1: do not add this object
               | (.[$i-1][$j - $o.weight][0] + $o.value) as $v2    # option 2: add it
               | (if $v1 > $v2 then
                       [$v1, .[$i-1][$j][1]]                       # do not add this object
                  else [$v2, .[$i-1][$j - $o.weight][1]+[$o.name]] # add it
                  end) as $mx
               | .[$i][$j] = $mx
             else
                 .[$i][$j] = .[$i-1][$j]
             end))
  | .[$n][W];


struct KPDSupply{T<:Integer}
    item::String
    weight::T
    value::T
    quant::T
end

KPDSupply{T<:Integer}(itm::AbstractString, w::T, v::T, q::T=one(T)) = KPDSupply(itm, w, v, q)
Base.show(io::IO, kdps::KPDSupply) = print(io, kdps.quant, " ", kdps.item, " ($(kdps.weight) kg, $(kdps.value) €)")

using MathProgBase, Cbc
function solve(gear::Vector{<:KPDSupply}, capacity::Integer)
    w = getfield.(gear, :weight)
    v = getfield.(gear, :value)
    sol = mixintprog(-v, w', '<', capacity, :Bin, 0, 1, CbcSolver())
    gear[sol.sol .≈ 1]
end


val Validate = fn jsonstring =>
let
 val Valid =  fn jsonstring =>
  let
   val json       =  String.translate (fn #"\"" => "\\\""|n=>str n ) jsonstring ;
   val textlength = (String.size json ) + 50 ;
   val app        = " jq -c '.' "
   val fname      = "/tmp/jsonval" ^ (String.extract (Time.toString (Posix.ProcEnv.time()),7,NONE) );
   val shellCommand = "echo  \"" ^ json ^ "\" | " ^ app
   val me         = (  Posix.FileSys.mkfifo (fname, Posix.FileSys.S.flags [ Posix.FileSys.S.irusr,Posix.FileSys.S.iwusr ] ) ;
                       Posix.Process.fork () ) ;
  in
   if (Option.isSome me) then
     let
        val fin =TextIO.openIn fname
     in
        ( Posix.Process.sleep (Time.fromReal 0.1) ;
          TextIO.inputN (fin,textlength) before
	  (TextIO.closeIn fin ; OS.FileSys.remove fname)
	)
     end
   else
     ( OS.Process.system ( shellCommand ^ " > " ^fname ^ " 2>&1 ") ;                                           (* remove fmt and validate *)
       "done\n" before OS.Process.exit OS.Process.success )
  end
 val result = Valid jsonstring
in
 if String.isPrefix "{" result then result else "JSON error\n"
end;

datatype ('a,'b) element = elem of 'a * 'b | markerb of int ;                       (*  <   internal structure   v   *)
datatype 'a content      = value of 'a | block of ('a,'a content) element list | arr of 'a content list |marker of int ;

exception Dtype of string ;
val unarr    =  fn arr lst => lst   |  _   =>  (raise Dtype "unarr"   ; []) ;
val unblock  =  fn block lst => lst |  _   =>  (raise Dtype "unblock" ; []) ;

(* --- example loop to apply a function 'dothis', which returns type jvals, to the structure  ---- *)

datatype jvals       = St of string | It of IntInf.int | Rl of real | Bl of bool ;        (* returned type by 'dothis' *)

val rec gothruAndDo = fn dothis => fn storedObject =>
   let
      val walk = fn elem ( n, value v)  => elem (dothis n , value (dothis v) )
                  | elem ( n, block v)  => elem (dothis n , block ( (gothruAndDo dothis)  (rev (tl (rev v)))) )
                  | elem ( n, arr v)    => elem (dothis n , arr ( List.map (block o (gothruAndDo dothis) o unblock)  (rev (tl (rev v))) ) )
		  | _                   => elem (St "", value (It (IntInf.fromInt ~1)))
   in
      List.map walk storedObject
 end;

(*  ------------------------------------  end of loop example  ------------------------------------ *)

local

exception Dtype of string ;
val markbToInt        =  fn markerb NrChars => NrChars | _  => (raise Dtype "markerb!" ; ~1) ;
val markToInt         =  fn  marker NrChars => NrChars |  _ => (raise Dtype "marker!"  ; ~1) ;

fun readarr rtag rc =  fn #"]"::S => [  marker (List.length S)   ]                                    (* process array *)
                        | S       => let val tmp = (rtag rc ("",S)) in  (block tmp)  ::
                                          ( readarr rtag rc (   List.drop (S,(List.length S) -   markbToInt ( hd (rev  tmp)))    ))  end ;

val rec readNaVa = fn rc : string * char list -> string content * char list   => fn
    ("",[])             => []
|   (sr,[])             =>   [ elem (sr, value "") ]
|   (sr,#":":: #"["::S) =>
                             let val tmp = arr (readarr readNaVa rc S) in                              (* field is array *)
                               ( elem (sr,  tmp )) :: (readNaVa rc ("" ,  List.drop (S,(List.length S) - (markToInt (hd (rev(unarr tmp)))) )     ))
			     end
|  (sr, #":":: #"{"::S) =>
                             let  val tmp = readNaVa rc ("",S )  in                                    (* field is object *)
                               ( elem (sr, block tmp)) :: (readNaVa rc ("" , List.drop (S,(List.length S) -(markbToInt ( hd (rev tmp))))    ))
                              end
|  (sr,#"}":: #","::S)  =>   [ markerb (List.length S) ]
|  (sr,#"}"::S)         =>   [ markerb (List.length S) ]
|  (sr,#":"::S)         =>
                             let val tmp = rc ("",S)  in                                                (* field is basic *)
                                elem ( sr, #1 tmp) :: (readNaVa rc ("",  #2  tmp ) )
                             end
|  (sr,#","::S)         =>   readNaVa rc (sr , S)
|  (sr,#"{"::a::S)      =>   readNaVa rc (sr^(str a) , S)
|  (sr,a::S)            =>   readNaVa rc (sr^(str a) , S)  ;                                            (* name field *)

 val rec readcontent = fn
   (sc,a::[])       => (value ( sc^(str a) ),[])
|  (sc,#","::t)     => (value  sc , t)
|  (sc, #"}"::t)    => (value  sc , #"}"::t)
|  (sc, #"]"::t)    => (value  sc , #"]"::t)
|  (sc, a::t)       => readcontent( ( sc^(str a) ),t) ;

val putall = fn input =>
 let
  val rec put  = fn
          []      => ""
    | (elem h)::t => (#1 h) ^ ":" ^ ( ( fn value x=> x
                                       | block x => "{" ^ (put x )
				       | arr x   => "["  ^  String.concat (( List.map (fn x=> "{"^( (put o unblock) x)^"," ) (rev (tl (rev x)))))  ^ "]" ) (#2 h))
					 ^ ","
					 ^ (put t)
    | (markerb h)::t => "}"
 in
   "{" ^ (put input)
 end;

val commas = fn tok => fn S =>
   ( Substring.concatWith (str tok)
     ( List.map (Substring.dropr (fn x=> x= #"," ))
          (Substring.tokens (fn x=> x= tok ) (Substring.full S) )) ) ^ (if tok = #"}" then str tok else "" )

in

  val storeJsString = fn input =>
      readNaVa readcontent ("" , String.explode (  Validate input ) )

  val writeJS = fn storedStruct =>
      ( ( ( commas #"}" ) o ( commas #"]" ) o putall ) storedStruct )

end ;


import Foundation

let jsonString = "{ \"foo\": 1, \"bar\": [10, \"apples\"] }"
if let jsonData = jsonString.data(using: .utf8) {
	if let jsonObject: Any = try? JSONSerialization.jsonObject(with: jsonData, options: .allowFragments) {
		print("Dictionary: \(jsonObject)")
	}
}

let obj = [
	"foo": [1, "Orange"],
	"bar": 1
] as [String : Any]

if let objData = try? JSONSerialization.data(withJSONObject: obj, options: .prettyPrinted) {
	if let jsonString2 = String(data: objData, encoding: .utf8) {
		print("JSON: \(jsonString2)")
	}
}


// Not all JSON object member keys can be represented, a fallback would need to be implemented
// Currently Tailspin only supports integers so for now we leave numbers as strings, as we do for true, false and null

templates hexToInt
  templates hexDigit
    <='0'> 0! <='1'> 1! <='2'> 2! <='3'> 3! <='4'> 4! <='5'> 5! <='6'> 6! <='7'> 7! <='8'> 8! <='9'> 9!
    <'[Aa]'> 10! <'[Bb]'> 11! <'[Cc]'> 12! <'[Dd]'> 13! <'[Ee]'> 14! <'[Ff]'> 15!
  end hexDigit
  @: 0;
  $... -> hexDigit -> @: [email protected] * 16 + $;
  [email protected] !
end hexToInt

composer jsonParser
  <value>
  rule value: (<WS>?) <string|number|object|array|true|false|null> (<WS>?)

  rule string: (<='"'>) <chars>  (<='"'>)
  rule chars: [ <quote|backslash|slash|backspace|formfeed|linefeed|return|tab|unicode|'[^"]'>* ] -> '$...;'
  rule quote: <='\"'> -> '"'
  rule backslash: <='\\'> -> '\'
  rule slash: <='\/'> -> '/'
  rule backspace: <='\b'> -> '$#8;'
  rule formfeed: <='\f'> -> '$#12;'
  rule linefeed: <='\n'> -> '$#10;'
  rule return: <='\r'> -> '$#13;'
  rule tab: <='\t'> -> '$#9;'
  rule unicode: (<='\u'>) <'[0-9A-Fa-f]{4}'> -> hexToInt -> '$#$;'

  rule number: <'-?(0|[1-9][0-9]*)(\.[0-9]+)?((e|E)(\+|-)?[0-9]+)?'> // TODO: represent this other than string

  rule object: (<='{'> <WS>?) { <keyValues>? } (<='}'>)
  rule keyValues: <keyValue> <followingKeyValue>*
  rule keyValue: <string>: (<WS>? <=':'>) <value>
  rule followingKeyValue: (<=','> <WS>?) <keyValue>

  rule array: (<='['>) [ <arrayValues>? ] (<=']'>)
  rule arrayValues: <value> <followingArrayValue>*
  rule followingArrayValue: (<=','>) <value>

  rule true: <='true'> // TODO: represent this other than string
  rule false: <='false'> // TODO: represent this other than string
  rule null: <='null'> // TODO: represent this other than string
end jsonParser

templates printJson
  templates printKeyValue
    '$::key -> printJson;: $::value -> printJson;' !
  end printKeyValue
  templates encodeChars
    <='"'> '\"' !
    <='\'> '\\' !
    <='/'> '\/' !
    <='$#8;'> '\b' !
    <='$#12;'> '\f' !
    <='$#10;'> '\n' !
    <='$#13;'> '\r' !
    <='$#9;'> '\t' !
    <> $ !
  end encodeChars
  $ -> #
  when <[]> do
    '[$(1) -> printJson;$(2..last)... -> ', $ -> printJson;';]' !
  when <{}> do
    [ $... ] -> '{$(1) -> printKeyValue;$(2..last)... -> ', $ -> printKeyValue;';}' !
  when <..0|0..> do
    '$;'!
  when <'.*'> do
    [ $... -> encodeChars ] -> '"$...;"' !
  otherwise 'WTF!' !
  // Other types do not yet exist in Tailspin
end printJson

'{ "foo": 1, "bar": [10, "apples"] }' -> jsonParser -> '$.bar(2);
' -> !OUT::write

{ blue: [1,2], ocean: 'water' } -> printJson -> '$;
' -> !OUT::write


package require json
set sample {{ "foo": 1, "bar": [10, "apples"] }}

set parsed [json::json2dict $sample]
puts $parsed


// version 1.1.2

data class Item(val name: String, val weight: Int, val value: Int)

val wants = listOf(
    Item("map", 9, 150),
    Item("compass", 13, 35),
    Item("water", 153, 200),
    Item("sandwich", 50, 160),
    Item("glucose", 15, 60),
    Item("tin", 68, 45),
    Item("banana", 27, 60),
    Item("apple", 39, 40),
    Item("cheese", 23, 30),
    Item("beer", 52, 10),
    Item("suntan cream", 11, 70),
    Item("camera", 32, 30),
    Item("T-shirt", 24, 15),
    Item("trousers", 48, 10),
    Item("umbrella", 73, 40),
    Item("waterproof trousers", 42, 70),
    Item("waterproof overclothes", 43, 75),
    Item("note-case", 22, 80),
    Item("sunglasses", 7, 20),
    Item("towel", 18, 12),
    Item("socks", 4, 50),
    Item("book", 30, 10)
)

const val MAX_WEIGHT = 400

fun m(i: Int, w: Int): Triple<MutableList<Item>, Int, Int> {
    val chosen = mutableListOf<Item>()
    if (i < 0 || w == 0) return Triple(chosen, 0, 0)
    else if (wants[i].weight > w) return m(i - 1, w)
    val (l0, w0, v0) = m(i - 1, w)
    var (l1, w1, v1) = m(i - 1, w - wants[i].weight)
    v1 += wants[i].value
    if (v1 > v0) {
        l1.add(wants[i])
        return Triple(l1, w1 + wants[i].weight, v1)
    }
    return Triple(l0, w0, v0)
}

fun main(args: Array<String>) {
    val (chosenItems, totalWeight, totalValue) = m(wants.size - 1, MAX_WEIGHT)
    println("Knapsack Item Chosen    Weight Value")
    println("----------------------  ------ -----")
    for (item in chosenItems.sortedByDescending { it.value} )
        println("${item.name.padEnd(24)}  ${"%3d".format(item.weight)}    ${"%3d".format(item.value)}")
    println("----------------------  ------ -----")
    println("Total ${chosenItems.size} Items Chosen     $totalWeight   $totalValue")
}


@(define value (v))@\
  @(cases)@\
    @(string v)@(or)@(num v)@(or)@(object v)@(or)@\
    @(keyword v)@(or)@(array v)@\
  @(end)@\
@(end)
@(define ws)@/[\n\t ]*/@(end)
@(define string (g))@\
  @(local s hex)@\
  @(ws)@\
  "@(coll :gap 0 :vars (s))@\
     @(cases)@\
       \"@(bind s """)@(or)@\
       \\@(bind s "\\\\")@(or)@\
       \/@(bind s "\\/")@(or)@\
       \[email protected](bind s "")@(or)@\
       \[email protected](bind s "�")@(or)@\
       \[email protected](bind s "
")@(or)@\
       \[email protected](bind s "
")@(or)@\
       \[email protected](bind s "	")@(or)@\
       \[email protected]{hex /[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]/}@\
         @(bind s `&#[email protected];`)@(or)@\
       @{s /[^"\\]*/}@(filter :to_html s)@\
     @(end)@\
     @(until)"@\
   @(end)"@\
  @(ws)@\
  @(cat s "")@\
  @(filter :from_html s)@\
  @(bind g ("S" s))@\
@(end)
@(define num (v))@\
  @(local n)@\
  @(ws)@{n /-?[0-9]+((\.[0-9]+)?([Ee][+\-]?[0-9]+)?)?/}@(ws)@\
  @(bind v ("N" n))@\
@(end)
@(define keyword (v))@\
  @(local k)@\
  @(all)@(ws)@{k /true|false|null/}@(trailer)@/[^A-Za-z0-9_]/@(end)@(ws)@\
  @(bind v ("K" k))@\
@(end)
@(define object (v))@\
  @(local p e pair)@\
  @(ws){@(ws)@(coll :gap 0 :vars (pair))@\
                @(string p):@(value e)@/,?/@\
                @(bind pair (p e))@\
                @(until)}@\
             @(end)}@(ws)@\
  @(bind v ("O" pair))@\
@(end)
@(define array (v))@\
  @(local e)@\
  @(ws)[@(ws)@(coll :gap 0 :var (e))@(value e)@/,?/@(until)]@(end)]@(ws)@\
  @(bind v ("A" e))@\
@(end)
@(freeform)
@(maybe)@(value v)@(end)@badsyntax


import json

struct User {
	// Adding a [required] attribute will make decoding fail, if that
	// field is not present in the input.
	// If a field is not [required], but is missing, it will be assumed
	// to have its default value, like 0 for numbers, or '' for strings,
	// and decoding will not fail.
	name string [required]
	age  int
	// Use the `skip` attribute to skip certain fields
	foo int [skip]
	// If the field name is different in JSON, it can be specified
	last_name string [json: lastName]
	possessions []string
}

fn main() {
	data := '{ "name": "Frodo", "lastName": "Baggins", "age": 25, "possessions": ["shirt","ring","sting"] }'
	user := json.decode(User, data) or {
		eprintln('Failed to decode json, error: $err')
		return
	}
	println(user)

	println(json.encode(user))
}


import "/json" for JSON

var s = "{ \"foo\": 1, \"bar\": [ \"10\", \"apples\"] }"
var o = JSON.parse(s)
System.print(o)

o = { "blue": [1, 2], "ocean": "water" }
s = JSON.stringify(o)
System.print(s)


let $json := '
{
  "Astring" : "string-value",
  "Anumber" : 5.7,
  "Anull"   : null,
  "Aarray"  : ["One","Two", 3],
  "Aobject" : {
               "key1": "value1",
               "key2": "value2"
             },
  "Atrue"   : true,
  "Afalse"  : false
}
'
let $xml := json-to-xml($local:json)
return (
 "XPath fn:json-to-xml#1 function:"
 ,""
 ,$xml
 ,""
 ,"Round trip, using fn:xml-to-json#1:"
 ,""
 ,xml-to-json($xml)
 ,""
 ,"Using BaseX json:parse#2 function to create an XPath 3.1 map:"
 ,""
 ,json:parse($local:json, map{"format":"xquery"})
)


string sNOTECARD = "Knapsack_Problem_0_1_Data.txt";
integer iMAX_WEIGHT = 400;
integer iSTRIDE = 4;
list lList = [];
default {
	integer iNotecardLine = 0;
	state_entry() {
		llOwnerSay("Reading '"+sNOTECARD+"'");
		llGetNotecardLine(sNOTECARD, iNotecardLine);
	}
	dataserver(key kRequestId, string sData) {
		if(sData==EOF) {
			//llOwnerSay("EOF");
			lList = llListSort(lList, iSTRIDE, FALSE);
			integer iTotalWeight = 0;
			integer iTotalValue = 0;
			list lKnapsack = [];
			integer x = 0;
			while(x*iSTRIDE<llGetListLength(lList)) {
				float fValueWeight = (float)llList2String(lList, x*iSTRIDE);
				string sItem = (string)llList2String(lList, x*iSTRIDE+1);
				integer iWeight = (integer)llList2String(lList, x*iSTRIDE+2);
				integer iValue = (integer)llList2String(lList, x*iSTRIDE+3);
				if(iTotalWeight+iWeight<iMAX_WEIGHT) {
					iTotalWeight += iWeight;
					iTotalValue += iValue;
					lKnapsack += [sItem, iWeight, iValue, fValueWeight];
				}
				x++;
			}
			for(x=0 ; x*iSTRIDE<llGetListLength(lKnapsack) ; x++) {
				llOwnerSay((string)x+": "+llList2String(lList, x*iSTRIDE+1)+", "+llList2String(lList, x*iSTRIDE+2)+", "+llList2String(lList, x*iSTRIDE+3));

			}
			llOwnerSay("iTotalWeight="+(string)iTotalWeight);
			llOwnerSay("iTotalValue="+(string)iTotalValue);
		} else {
			//llOwnerSay((string)iNotecardLine+": "+sData);
			if(llStringTrim(sData, STRING_TRIM)!="") {
				list lParsed = llParseString2List(sData, [","], []);
				string sItem = llStringTrim(llList2String(lParsed, 0), STRING_TRIM);
				integer iWeight = (integer)llStringTrim(llList2String(lParsed, 1), STRING_TRIM);
				integer iValue = (integer)llStringTrim(llList2String(lParsed, 2), STRING_TRIM);
				float fValueWeight = (1.0*iValue)/iWeight;
				lList += [fValueWeight, sItem, iWeight, iValue];
			}
			llGetNotecardLine(sNOTECARD, ++iNotecardLine);
		}
	}
}


items = {
    {"map", 9, 150},
    {"compass", 13, 35},
    {"water", 153, 200},
    {"sandwich", 50, 160},
    {"glucose", 15, 60},
    {"tin", 68, 45},
    {"banana", 27, 60},
    {"apple", 39,  40},
    {"cheese", 23, 30},
    {"beer", 52, 10},
    {"suntan cream", 11, 70},
    {"camera", 32, 30},
    {"t-shirt", 24, 15},
    {"trousers", 48, 10},
    {"umbrella", 73, 40},
    {"waterproof trousers", 42, 70},
    {"waterproof overclothes", 43, 75},
    {"note-case", 22, 80},
    {"sunglasses", 7, 20},
    {"towel", 18, 12},
    {"socks", 4, 50},
    {"book", 30, 10},
}

local unpack = table.unpack

function m(i, w)
    if i<1 or w==0 then
        return 0, {}
    else
        local _, wi, vi = unpack(items[i])
        if wi > w then
            return mm(i - 1, w)
        else
            local vn, ln = mm(i - 1, w)
            local vy, ly = mm(i - 1, w - wi)
            if vy + vi > vn then
                return vy + vi, { i, ly }
            else
                return vn, ln
            end
        end
    end
end

local memo, mm_calls = {}, 0
function mm(i, w) -- memoization function for m
    mm_calls = mm_calls + 1
    local key = 10000*i + w
    local result = memo[key]
    if not result then
        result = { m(i, w) }
        memo[key] = result
    end
    return unpack(result)
end

local total_value, index_list = m(#items, 400)

function list_items(head) -- makes linked list iterator function
    return function()
        local item, rest = unpack(head)
        head = rest
        return item
    end
end

local names = {}
local total_weight = 0
for i in list_items(index_list) do
    local name, weight = unpack(items[i])
    table.insert(names, 1, name)
    total_weight = total_weight + weight
end

local function printf(fmt, ...) print(string.format(fmt, ...)) end
printf("items to pack: %s", table.concat(names, ", "))
printf("total value: %d", total_value)
printf("total weight: %d", total_weight)

-- out of curiosity
local count = 0
for k,v in pairs(memo) do count = count + 1 end
printf("\n(memo count: %d; mm call count: %d)", count, mm_calls)


a,b:=Import.lib("zklYAJL");
var [const] YAJL=a, toJSON=b;
src:=
#<<<
0'|{
    "pi": 3.14,
    "large number": 123456789123456791,
    "an array": [
        -1,
        true,
        false,
        null,
        "foo"
    ]
}|;
#<<<
obj:=YAJL().write(src).close();
// or obj:=src.pump(YAJL()).close(); // for example, from file or socket
obj.println();


weights := [9,13,153,50,15,68,27,39,23,52,11,32,24,48,73,42,43,22,7,18,4,30]:
vals := [150,35,200,160,60,45,60,40,30,10,70,30,15,10,40,70,75,80,20,12,50,10]:
items := ["map","compass","water","sandwich","glucose","tin","banana","apple","cheese","beer","suntan cream","camera","T-shirt","trousers","umbrella","waterproof trousers","waterproof overclothes","note-case","sunglasses","towel","socks","book"]:
acc := Array(1..numelems(vals)+1,1..400+1,1,fill=0):
len := numelems(weights):
for i from 2 to len+1 do #number of items picked + 1
	for j from 2 to 401 do #weight capacity left + 1
		if weights[i-1] > j-1 then
			acc[i,j] := acc[i-1, j]:
		else
			acc[i,j] := max(acc[i-1,j], acc[i-1, j-weights[i-1]]+vals[i-1]):
		end if:
	end do:
end do:
printf("Total Value is %d\n", acc[len+1, 401]):
count := 0:
i := len+1:
j := 401:
while (i>1 and j>1) do
	if acc[i,j] <> acc[i-1,j] then
		printf("Item: %s\n", items[i-1]):
		count := count+weights[i-1]:
		j := j-weights[i-1]:
		i := i-1:
	else
		i := i-1:
	end if:
end do:
printf("Total Weight is %d\n", count):


/*Knapsack

  This model finds the integer optimal packing of a knapsack

  Nigel_Galloway
  January 9th., 2012
*/

set Items;
param weight{t in Items};
param value{t in Items};

var take{t in Items}, binary;

knap_weight : sum{t in Items} take[t] * weight[t] <= 400;

maximize knap_value: sum{t in Items} take[t] * value[t];

data;

param : Items          : weight   value :=
         map		  9	   150
         compass          13	   35
         water		  153	   200
         sandwich	  50	   160
         glucose	  15	   60
         tin		  68	   45
         banana		  27	   60
         apple		  39	   40
         cheese		  23	   30
         beer		  52	   10
         suntancream	  11	   70
         camera		  32	   30
         T-shirt	  24	   15
         trousers	  48	   10
         umbrella	  73	   40
         w-trousers	  42	   70
         w-overclothes	  43	   75
         note-case	  22	   80
         sunglasses	  7        20
         towel		  18	   12
         socks		  4        50
         book		  30	   10
;

end;


global globalItems = #()
global usedMass = 0
global neededItems = #()
global totalValue = 0
struct kn_item
(
	item, weight, value
)

itemStrings = #("map#9#150","compass#13#35","water#153#200", \
		"sandwich#50#160","glucose#15#60","tin#68#45", \
		"banana#27#60","apple#39#40","cheese#23#30", \
		"beer#52#10","suntan cream#11#70","camera#32#30", \
		"T-shirt#24#15","trousers#48#10","umbrella#73#40", \
		"waterproof trousers#42#70","waterproof overclothes#43#75", \
		"note-case#22#80","sunglasses#7#20", "towel#18#12", \
		"socks#4#50","book#30#10")

fn sortByValue a b =
(
	if a[1].value > b[1].value then return -1
	else
	(
		if a[1].value == b[1].value then return 0
			else return 1
	)
)
fn chooseBestItem maximumWeight: items: =
(
	local itemsCopy = deepcopy items
	local possibleItems = #()
	for i = 1 to itemsCopy.count do
	(
		if itemsCopy[i].weight <= maximumWeight do append possibleItems (#(itemsCopy[i],i))
	)
	qsort possibleItems sortByValue
	if possibleItems.count > 0 then return possibleItems[1] else return 0
)

for i = 1 to itemStrings.count do
(
	local split = filterstring itemStrings[i] "#"
	local itemStruct = kn_item item:split[1] weight:(split[2] as integer) \
				value:(split[3] as integer)
	appendifunique globalItems itemstruct
)

while usedMass < 400 do
(
	local item = chooseBestItem maximumweight:(400-usedMass) items:(globalItems)
	if item != 0 then
	(
		deleteitem globalItems (item[2])
		appendifunique neededItems item[1]
		usedMass += item[1].weight
	) else exit
)
for i in neededitems do
(
	format "Item name: %, weight: %, value:%\n" i.item i.weight i.value
	totalValue += i.value
)
format "Total mass: %, Total Value: %\n" usedMass totalValue


%Knapsack 0/1. Nigel Galloway: October 5th., 2020.
enum Items={map,compass,water,sandwich,glucose,tin,banana,apple,cheese,beer,suntan_cream,camera,t_shirt,trousers,umbrella,waterproof_trousers,waterproof_overclothes,note_case,sunglasses,towel,socks,book};
array[Items] of int: weight=[9,13,153,50,15,68,27,39,23,52,11,32,24,48,73,42,43,22,7,18,4,30];
array[Items] of int: value =[150,35,200,160,60,45,60,40,30,10,70,30,15,10,40,70,75,80,20,12,50,10];
int: maxWeight=400;
var int: wTaken=sum(n in take)(weight[n]);
var int: wValue=sum(n in take)(value[n]);
var set of Items: take;
constraint wTaken <= maxWeight;
solve maximize wValue;
output["Take "++show(take)++"\nTotal Weight=\(wTaken) Total Value=\(wValue)"]


# Knapsack. Recursive algorithm.

import algorithm
import sequtils
import tables

# Description of an item.
type Item = tuple[name: string; weight, value: int]

# List of available items.
const Items: seq[Item] = @[("map", 9, 150),
                           ("compass", 13, 35),
                           ("water", 153, 200),
                           ("sandwich", 50, 160),
                           ("glucose", 15, 60),
                           ("tin", 68, 45),
                           ("banana", 27, 60),
                           ("apple", 39, 40),
                           ("cheese", 23, 30),
                           ("beer", 52, 10),
                           ("suntan cream", 11, 70),
                           ("camera", 32, 30),
                           ("T-shirt", 24, 15),
                           ("trousers", 48, 10),
                           ("umbrella", 73, 40),
                           ("waterproof trousers", 42, 70),
                           ("waterproof overclothes", 43, 75),
                           ("note-case", 22, 80),
                           ("sunglasses", 7, 20),
                           ("towel", 18, 12),
                           ("socks", 4, 50),
                           ("book", 30, 10)
                          ]

type

  # Item numbers (used rather than items themselves).
  Number = range[0..Items.high]

  # Chosen items and their total value.
  Choice = tuple[nums: set[Number]; weight, value: int]

# Cache used to speed up the search.
var cache: Table[tuple[num, weight: int], Choice]

#---------------------------------------------------------------------------------------------------

proc select(num, weightLimit: int): Choice =
  ## Find the best choice starting from item at index "num".

  if num < 0 or weightLimit == 0:
    return

  if (num, weightLimit) in cache:
    return cache[(num, weightLimit)]

  let weight = Items[num].weight
  if weight > weightLimit:
    return select(num - 1, weightLimit)

  # Try by leaving this item and selecting among remaining items.
  result = select(num - 1, weightLimit)

  # Try by taking this item and completing with some remaining items.
  var result1 = select(num - 1, weightLimit - weight)
  inc result1.value, Items[num].value

  # Select the best choice (giving the greater value).
  if result1.value > result.value:
    result = (result1.nums + {num.Number}, result1.weight + weight, result1.value)

  cache[(num, weightLimit)] = result

#---------------------------------------------------------------------------------------------------

let (nums, weight, value) = select(Items.high, 400)
echo "List of items:"
for num in sorted(toSeq(nums)):
  echo "– ", Items[num].name
echo ""
echo "Total weight: ", weight
echo "Total value: ", value


let items = [
  "map",                     9,  150;
  "compass",                13,   35;
  "water",                 153,  200;
  "sandwich",               50,  160;
  "glucose",                15,   60;
  "tin",                    68,   45;
  "banana",                 27,   60;
  "apple",                  39,   40;
  "cheese",                 23,   30;
  "beer",                   52,   10;
  "suntan cream",           11,   70;
  "camera",                 32,   30;
  "t-shirt",                24,   15;
  "trousers",               48,   10;
  "umbrella",               73,   40;
  "waterproof trousers",    42,   70;
  "waterproof overclothes", 43,   75;
  "note-case",              22,   80;
  "sunglasses",              7,   20;
  "towel",                  18,   12;
  "socks",                   4,   50;
  "book",                   30,   10;
]

let comb =
  List.fold_left (fun acc x -> let acc2 = List.rev_map (fun li -> x::li) acc in
                                 List.rev_append acc acc2) [[]]

let score =
  List.fold_left (fun (w_tot,v_tot) (_,w,v) -> (w + w_tot, v + v_tot)) (0,0)

let () =
  let combs = comb items in
  let vals = List.rev_map (fun this -> (score this, this)) combs in
  let poss = List.filter (fun ((w,_), _) -> w <= 400) vals in
  let _, res = List.fold_left (fun (((_,s1),_) as v1) (((_,s2),_) as v2) ->
                 if s2 > s1 then v2 else v1)
                 (List.hd poss) (List.tl poss) in
  List.iter (fun (name,_,_) -> print_endline name) res;
;;


declare
  %% maps items to pairs of Weight(hectogram) and Value
  Problem = knapsack('map':9#150
                     'compass':13#35
                     'water':153#200
                     'sandwich':50#160
                     'glucose':15#60
                     'tin':68#45
                     'banana':27#60
                     'apple':39#40
                     'cheese':23#30
                     'beer':52#10
                     'suntan cream':11#70
                     'camera':32#30
                     't-shirt':24#15
                     'trousers':48#10
                     'umbrella':73#40
                     'waterproof trousers':42#70
                     'waterproof overclothes':43#75
                     'note-case':22#80
                     'sunglasses':7#20
                     'towel':18#12
                     'socks':4#50
                     'book':30#10
                    )

  %% item -> Weight
  Weights = {Record.map Problem fun {$ X} X.1 end}
  %% item -> Value
  Values =  {Record.map Problem fun {$ X} X.2 end}

  proc {Knapsack Solution}
     %% a solution maps items to finite domain variables
     %% with the domain {0,1}
     Solution = {Record.map Problem fun {$ _} {FD.int 0#1} end}
     %% no more than 400 hectograms
     {FD.sumC Weights Solution '=<:' 400}
     %% search through valid solutions
     {FD.distribute naive Solution}
  end

  proc {PropagateLargerValue Old New}
     %% propagate that new solutions must yield a higher value
     %% than previously found solutions (essential for performance)
     {FD.sumC Values New '>:' {Value Old}}
  end

  fun {Value Candidate}
     {Record.foldL {Record.zip Candidate Values Number.'*'} Number.'+' 0}
  end

  fun {Weight Candidate}
     {Record.foldL {Record.zip Candidate Weights Number.'*'} Number.'+' 0}
  end

  [Best] = {SearchBest Knapsack PropagateLargerValue}
in
  {System.showInfo "Items: "}
  {ForAll
     {Record.arity {Record.filter Best fun {$ T} T == 1 end}}
     System.showInfo}
  {System.printInfo "\n"}
  {System.showInfo "total value: "#{Value Best}}
  {System.showInfo "total weight: "#{Weight Best}}


F j(n, k)
   V p = Array(0 .< n)
   V i = 0
   [Int] seq
   L !p.empty
      i = (i + k - 1) % p.len
      seq.append(p.pop(i))
   R "Prisoner killing order: #..\nSurvivor: #.".format(seq[0 .< (len)-1].join(‘, ’), seq.last)

print(j(5, 2))
print(j(41, 3))


program project1;
uses
  sysutils, classes, math;

const
  MaxWeight = 400;
  N = 21;

type
  TMaxArray = array[0..N, 0..MaxWeight] of integer;

  TEquipment = record
    Description : string;
    Weight : integer;
    Value : integer;
  end;

  TEquipmentList = array[1..N] of TEquipment;

var
   M:TMaxArray;
   MaxValue, WeightLeft, i, j, Sum : integer;
   S,KnapSack:TStringList;
   L:string;
   List:TEquipmentList;

begin
   //Put all the items into an array called List
   L:='map ,9 ,150,compass ,13 ,35 ,water ,153 ,200 ,sandwich,50 ,160 ,glucose ,15 ,60 ,tin,68 ,45 ,banana,27,60 ,apple ,39 ,40 ,cheese ,23 ,30 ,beer ,52 ,10 ,suntancreme ,11 ,70 ,camera ,32 ,30 ,T-shirt ,24 ,15 ,trousers ,48 ,40 ,waterprooftrousers ,42 ,70 ,waterproofoverclothes ,43 ,75 ,notecase ,22 ,80 ,sunglasses ,7 ,20 ,towel ,18 ,12 ,socks ,4 ,50 ,book ,30 ,10';
   S:=TStringList.create;
   S.Commatext:=L;

   For i:= 1 to N do
   begin
      List[i].Description:=S[3*i - 3];
      List[i].Weight:=strtoint(S[3*i - 2]);
      List[i].Value:=strtoint(S[3*i - 1]);
   end;

   //create M, a table linking the possible items for each weight
   //and recording the value at that point
   for j := 0 to MaxWeight do
       M[0, j] := 0

   for i := 1 to N do
       for j := 0 to MaxWeight do
           if List[i].weight > j then
               M[i, j] := M[i-1, j]
           else
               M[i, j] := max(M[i-1, j], M[i-1, j-List[i].weight] + List[i].value);

   //get the highest total value by testing every value in table M
   for i:=1 to N do
       for j:= 0 to MaxWeight do
           If M[i,j] > MaxValue then
               MaxValue := m[i,j];

   writeln('Highest total value : ',MaxValue);

  //Work backwards through the items to find those items that go in the Knapsack (a stringlist)
   KnapSack := TStringList.create;
   WeightLeft := MaxWeight;
   For i:= N downto 1 do
       if M[i,WeightLeft] = MaxValue then
          if M[i-1, WeightLeft - List[i].Weight] = MaxValue - List[i].Value then
          begin
            Knapsack.add(List[i].Description + ' ' + IntToStr(List[i].Weight)+ ' ' + inttostr(List[i].Value));
            MaxValue := MaxValue - List[i].Value;
            WeightLeft := WeightLeft - List[i].Weight;
          end

   //Show the items in the knapsack
   writeln('Number of items     : ',KnapSack.count);
   writeln('-------------------------');
   For i:= KnapSack.count-1 downto 0 do
     writeln(KnapSack[i]);

   KnapSack.free;
   S.free;
   writeln('-------------------------');
   writeln('done');
   readln;
end.