Probably very simple....but stumps me :-(
Any explanation would be appreciated...
Why is line 25:
lastStoneWeight(weights.mapIt(Stone(weight: it)).toHeapQueue)
not equivalent to commented out lines at 23-24:
var stones = weights.mapIt(Stone(weight: it)).toHeapQueue
result = lastStoneWeight(stones)
It is just a simple substitution. No?
The first variant works and second genrates as big scary compilation error message (see below)
# See: http://leetcode.com/problems/last-stone-weight/
import sequtils, std/heapqueue # See: https://nim-lang.org/docs/heapqueue.html
type
Stone = object
weight: int
Stones = Heapqueue[Stone]
proc `<`(a, b: Stone): bool = b.weight < a.weight # maxHeap ordering for score
proc lastStoneWeight(stones: var Stones): int =
case stones.len:
of 0: 0
of 1: stones.pop.weight
else:
let (weight1, weight2) = (stones.pop.weight, stones.pop.weight)
let weightDiff = weight1 - weight2
if weightDiff > 0: stones.push Stone(weight: weightDiff)
lastStoneWeight stones
proc lastStoneWeight(weights: openArray[int]): int =
# var stones = weights.mapIt(Stone(weight: it)).toHeapQueue
# result = lastStoneWeight(stones)
lastStoneWeight(weights.mapIt(Stone(weight: it)).toHeapQueue)
proc test() =
assert lastStoneWeight([1]) == 1
assert lastStoneWeight([1,1]) == 0
assert lastStoneWeight([1,3]) == 2
assert lastStoneWeight([3,8,12]) == 1
assert lastStoneWeight([1,3,8,12]) == 0
assert lastStoneWeight([2,7,4,1,8,1]) == 1
if isMainModule: test()
Error text for the second variant:
/Users/DM/work/trunk/coding_dojo/lastStoneWeight.nim(23, 18) Error: type mismatch: got <HeapQueue[lastStoneWeight.Stone]>
but expected one of:
proc lastStoneWeight(stones: var Stones): int
first type mismatch at position: 1
required type for stones: var Stones
but expression 'toHeapQueue(
type
OutType`gensym1 = typeof(
block:
var it: typeof(items(weights), typeOfIter)
Stone(weight: it), typeOfProc)
block:
template s2_452985056(): untyped =
weights
var i`gensym1 = 0
var result`gensym1 = newSeq(len(weights))
for it in items(weights):
result`gensym1[i`gensym1] = Stone(weight: it)
i`gensym1 += 1
result`gensym1)' is immutable, not 'var'
proc lastStoneWeight(weights: openArray[int]): int
first type mismatch at position: 1
required type for weights: openArray[int]
but expression 'toHeapQueue(
type
OutType`gensym1 = typeof(
block:
var it: typeof(items(weights), typeOfIter)
Stone(weight: it), typeOfProc)
block:
template s2_452985056(): untyped =
weights
var i`gensym1 = 0
var result`gensym1 = newSeq(len(weights))
for it in items(weights):
result`gensym1[i`gensym1] = Stone(weight: it)
i`gensym1 += 1
result`gensym1)' is of type: HeapQueue[lastStoneWeight.Stone]
expression: lastStoneWeight(toHeapQueue(
type
OutType`gensym1 = typeof(
block:
var it: typeof(items(weights), typeOfIter)
Stone(weight: it), typeOfProc)
block:
template s2_452985056(): untyped =
weights
var i`gensym1 = 0
var result`gensym1 = newSeq(len(weights))
for it in items(weights):
result`gensym1[i`gensym1] = Stone(weight: it)
i`gensym1 += 1
result`gensym1))
in the first lastStoneWeight, proc lastStoneWeight(stones: var Stones): int, it requires a var.
var stones = weights.mapIt(Stone(weight: it)).toHeapQueue makes a var or a variable to a mutable value, okay, and you pass it. result = lastStoneWeight(stones)
but here, lastStoneWeight(weights.mapIt(Stone(weight: it)).toHeapQueue), there is no var being made, and you pass it an immutable value.
Thanks… mystery solved…
As to why the compiler doesn’t realize it is being passed into a proc requiring a var and accommodating is interesting.