Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions exercises/practice/grade-school/.meta/example.v
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ fn add_student(roster map[int][]string, name string, grade int) map[int][]string
}
}

// Make sure that there is a list to append to
if grade !in new_roster {
new_roster[grade] = []
}

// append the new name and sort
new_roster[grade] << name
new_roster[grade].sort()
Expand Down
113 changes: 58 additions & 55 deletions exercises/practice/zebra-puzzle/.meta/example.v
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import datatypes
struct Constraint {
updates Property
depends_on []Property
checker fn (possible_values []u8, other_possible_values []u8) []u8 @[required]
checker fn (possible_values []int, other_possible_values []int) []int @[required]
}

struct Constraints {
Expand All @@ -14,19 +14,19 @@ mut:
interests map[int][]Constraint
}

enum Property as u8 {
enum Property {
// Colors
red
green
ivory
yellow
blue
// Smokes
kools
old_gold
chesterfields
lucky_strike
parliament
// Activities
painting
dancing
reading
football
chess
// Drinks
coffee
tea
Expand All @@ -48,8 +48,8 @@ enum Property as u8 {
end_property
}

fn solve() [][]u8 {
mut possible_values := [][]u8{len: int(Property.end_property), init: [u8(1), 2, 3, 4, 5]}
fn solve() [][]int {
mut possible_values := [][]int{len: int(Property.end_property), init: [1, 2, 3, 4, 5]}
mut constraints := Constraints{}

constraints.same_house(Property.englishman, Property.red)
Expand All @@ -62,28 +62,28 @@ fn solve() [][]u8 {
constraints.same_house(Property.tea, Property.ukrainian)
constraints.is_next_to(Property.green, Property.ivory, 1)
constraints.is_next_to(Property.ivory, Property.green, -1)
constraints.same_house(Property.old_gold, Property.snails)
constraints.same_house(Property.snails, Property.old_gold)
constraints.same_house(Property.kools, Property.yellow)
constraints.same_house(Property.yellow, Property.kools)
constraints.same_house(Property.dancing, Property.snails)
constraints.same_house(Property.snails, Property.dancing)
constraints.same_house(Property.painting, Property.yellow)
constraints.same_house(Property.yellow, Property.painting)
constraints.at_house(Property.milk, 3)
constraints.at_house(Property.norwegian, 1)
constraints.is_either_side(Property.chesterfields, Property.fox)
constraints.is_either_side(Property.fox, Property.chesterfields)
constraints.is_either_side(Property.kools, Property.horse)
constraints.is_either_side(Property.horse, Property.kools)
constraints.same_house(Property.lucky_strike, Property.orange_juice)
constraints.same_house(Property.orange_juice, Property.lucky_strike)
constraints.same_house(Property.japanese, Property.parliament)
constraints.same_house(Property.parliament, Property.japanese)
constraints.is_either_side(Property.reading, Property.fox)
constraints.is_either_side(Property.fox, Property.reading)
constraints.is_either_side(Property.painting, Property.horse)
constraints.is_either_side(Property.horse, Property.painting)
constraints.same_house(Property.football, Property.orange_juice)
constraints.same_house(Property.orange_juice, Property.football)
constraints.same_house(Property.japanese, Property.chess)
constraints.same_house(Property.chess, Property.japanese)
constraints.is_either_side(Property.norwegian, Property.blue)
constraints.is_either_side(Property.blue, Property.norwegian)

constraints.add_mutually_exclusive_constraints([Property.red, Property.green, Property.ivory,
Property.yellow, Property.blue])

constraints.add_mutually_exclusive_constraints([Property.kools, Property.old_gold,
Property.chesterfields, Property.lucky_strike, Property.parliament])
constraints.add_mutually_exclusive_constraints([Property.painting, Property.dancing,
Property.reading, Property.football, Property.chess])

constraints.add_mutually_exclusive_constraints([Property.coffee, Property.tea, Property.milk,
Property.orange_juice, Property.water])
Expand All @@ -99,7 +99,7 @@ fn solve() [][]u8 {
to_test := get_unsolved(possible_values) or { panic('Unexpected error') }
for property, candidates in to_test {
for value in candidates {
if value in possible_values[int(property)] {
if value in possible_values[property] {
mut test_copy := possible_values.clone()
test_copy[property] = [value]
constraints.run(mut test_copy)
Expand All @@ -124,13 +124,13 @@ fn solve() [][]u8 {
return possible_values
}

fn get_unsolved(possible_values [][]u8) !map[int][]u8 {
mut unsolved := map[int][]u8{}
fn get_unsolved(possible_values [][]int) !map[int][]int {
mut unsolved := map[int][]int{}
for property, values in possible_values {
if values.len == 0 {
return error('Empty possible values')
} else if values.len > 1 {
unsolved[int(property)] = values
unsolved[property] = values
}
}

Expand All @@ -140,45 +140,49 @@ fn get_unsolved(possible_values [][]u8) !map[int][]u8 {
fn (mut c Constraints) add(constraint Constraint) {
c.all_constraints << constraint
for _, property_of_interest in constraint.depends_on {
c.interests[int(property_of_interest)] << constraint
property_key := int(property_of_interest)
if property_key !in c.interests {
c.interests[property_key] = []
}
c.interests[property_key] << constraint
}
}

fn (mut c Constraints) at_house(property Property, house u8) {
fn (mut c Constraints) at_house(property Property, house int) {
c.add(Constraint{
updates: property
updates: property
depends_on: []
checker: fn [house] (possible_values []u8, other_possible_values []u8) []u8 {
checker: fn [house] (possible_values []int, other_possible_values []int) []int {
return [house]
}
})
}

fn (mut c Constraints) same_house(update_property Property, other_property Property) {
c.add(Constraint{
updates: update_property
updates: update_property
depends_on: [other_property]
checker: fn (possible_values []u8, other_possible_values []u8) []u8 {
checker: fn (possible_values []int, other_possible_values []int) []int {
return possible_values.filter(it in other_possible_values)
}
})
}

fn (mut c Constraints) is_next_to(update_property Property, other_property Property, offset int) {
c.add(Constraint{
updates: update_property
updates: update_property
depends_on: [other_property]
checker: fn [offset] (possible_values []u8, other_possible_values []u8) []u8 {
return possible_values.filter(u8(int(it) - offset) in other_possible_values)
checker: fn [offset] (possible_values []int, other_possible_values []int) []int {
return possible_values.filter((it - offset) in other_possible_values)
}
})
}

fn (mut c Constraints) is_either_side(update_property Property, other_property Property) {
c.add(Constraint{
updates: update_property
updates: update_property
depends_on: [other_property]
checker: fn (possible_values []u8, other_possible_values []u8) []u8 {
checker: fn (possible_values []int, other_possible_values []int) []int {
return possible_values.filter((it + 1) in other_possible_values
|| (it - 1) in other_possible_values)
}
Expand All @@ -198,9 +202,9 @@ fn (mut c Constraints) add_mutually_exclusive_constraints(group []Property) {

fn mutually_exclusive(update_property Property, other_property Property) Constraint {
return Constraint{
updates: update_property
updates: update_property
depends_on: [other_property]
checker: fn (possible_values []u8, other_possible_values []u8) []u8 {
checker: fn (possible_values []int, other_possible_values []int) []int {
if other_possible_values.len == 1 {
return possible_values.filter(it != other_possible_values[0])
}
Expand All @@ -211,9 +215,9 @@ fn mutually_exclusive(update_property Property, other_property Property) Constra

fn last_possible_house(update_property Property, other_properties []Property) Constraint {
return Constraint{
updates: update_property
updates: update_property
depends_on: other_properties
checker: fn (possible_values []u8, other_possible_values []u8) []u8 {
checker: fn (possible_values []int, other_possible_values []int) []int {
exclusive := possible_values.filter(it !in other_possible_values)
if exclusive.len == 1 {
return exclusive
Expand All @@ -223,18 +227,18 @@ fn last_possible_house(update_property Property, other_properties []Property) Co
}
}

fn (c Constraints) run(mut possible_values [][]u8) {
fn (c Constraints) run(mut possible_values [][]int) {
mut queue := datatypes.Queue[Constraint]{}
for constraint in c.all_constraints {
queue.push(constraint)
}

for !queue.is_empty() {
next := queue.pop() or { return }
current_values := possible_values[int(next.updates)]
mut other_values := []u8{}
current_values := possible_values[next.updates]
mut other_values := []int{}
for other_property in next.depends_on {
other_values << possible_values[int(other_property)]
other_values << possible_values[other_property]
}

updated_values := next.checker(current_values, other_values)
Expand All @@ -249,14 +253,13 @@ fn (c Constraints) run(mut possible_values [][]u8) {
}
}

fn find_who(possible_values [][]u8, property Property) string {
value := possible_values[int(property)]
return match value {
possible_values[int(Property.englishman)] { 'Englishman' }
possible_values[int(Property.spaniard)] { 'Spaniard' }
possible_values[int(Property.ukrainian)] { 'Ukrainian' }
possible_values[int(Property.norwegian)] { 'Norwegian' }
possible_values[int(Property.japanese)] { 'Japanese' }
fn find_who(possible_values [][]int, property Property) string {
return match possible_values[property] {
possible_values[Property.englishman] { 'Englishman' }
possible_values[Property.spaniard] { 'Spaniard' }
possible_values[Property.ukrainian] { 'Ukrainian' }
possible_values[Property.norwegian] { 'Norwegian' }
possible_values[Property.japanese] { 'Japanese' }
else { panic('Something has gone wrong, could not match house') }
}
}
Expand Down
Loading