From 6bf4b90c90f15f4ab60833bddf5b5756d1a6b1f6 Mon Sep 17 00:00:00 2001 From: Elizabeth Alexander Hunt Date: Thu, 2 Jul 2026 11:55:17 -0700 Subject: Init --- Homework/cs4700/dart/fractal.dart | 161 +++++++++++++++++++++ Homework/cs4700/dart/streams.dart | 106 ++++++++++++++ Homework/cs4700/kotlin/Lists.kt | 154 ++++++++++++++++++++ Homework/cs4700/kotlin/META-INF/main.kotlin_module | Bin 0 -> 50 bytes Homework/cs4700/kotlin/Main.kt | 85 +++++++++++ Homework/cs4700/kotlin/lists.jar | Bin 0 -> 4697257 bytes .../cs4700/kotlin/lists/ListsKt$compose$1.class | Bin 0 -> 1342 bytes .../kotlin/lists/ListsKt$composeList$1.class | Bin 0 -> 1032 bytes .../kotlin/lists/ListsKt$composeList$2$1.class | Bin 0 -> 1311 bytes Homework/cs4700/kotlin/lists/ListsKt$main$1.class | Bin 0 -> 1468 bytes .../cs4700/kotlin/lists/ListsKt$main$f$1.class | Bin 0 -> 1377 bytes .../cs4700/kotlin/lists/ListsKt$main$f$2.class | Bin 0 -> 1377 bytes Homework/cs4700/kotlin/lists/ListsKt.class | Bin 0 -> 9880 bytes Homework/cs4700/kotlin/lists/MainKt$main$1.class | Bin 0 -> 1423 bytes Homework/cs4700/kotlin/lists/MainKt$main$2.class | Bin 0 -> 1423 bytes Homework/cs4700/kotlin/lists/MainKt$main$3.class | Bin 0 -> 1423 bytes .../kotlin/lists/MainKt$main$functionList$1.class | Bin 0 -> 1353 bytes .../kotlin/lists/MainKt$main$functionList$2.class | Bin 0 -> 1353 bytes .../kotlin/lists/MainKt$main$functionList$3.class | Bin 0 -> 1353 bytes Homework/cs4700/kotlin/lists/MainKt.class | Bin 0 -> 5079 bytes Homework/cs4700/kotlin/main.jar | Bin 0 -> 4701863 bytes Homework/cs4700/prolog/castle.pl | 97 +++++++++++++ Homework/cs4700/prolog/test.pl | 51 +++++++ 23 files changed, 654 insertions(+) create mode 100644 Homework/cs4700/dart/fractal.dart create mode 100644 Homework/cs4700/dart/streams.dart create mode 100644 Homework/cs4700/kotlin/Lists.kt create mode 100644 Homework/cs4700/kotlin/META-INF/main.kotlin_module create mode 100644 Homework/cs4700/kotlin/Main.kt create mode 100644 Homework/cs4700/kotlin/lists.jar create mode 100644 Homework/cs4700/kotlin/lists/ListsKt$compose$1.class create mode 100644 Homework/cs4700/kotlin/lists/ListsKt$composeList$1.class create mode 100644 Homework/cs4700/kotlin/lists/ListsKt$composeList$2$1.class create mode 100644 Homework/cs4700/kotlin/lists/ListsKt$main$1.class create mode 100644 Homework/cs4700/kotlin/lists/ListsKt$main$f$1.class create mode 100644 Homework/cs4700/kotlin/lists/ListsKt$main$f$2.class create mode 100644 Homework/cs4700/kotlin/lists/ListsKt.class create mode 100644 Homework/cs4700/kotlin/lists/MainKt$main$1.class create mode 100644 Homework/cs4700/kotlin/lists/MainKt$main$2.class create mode 100644 Homework/cs4700/kotlin/lists/MainKt$main$3.class create mode 100644 Homework/cs4700/kotlin/lists/MainKt$main$functionList$1.class create mode 100644 Homework/cs4700/kotlin/lists/MainKt$main$functionList$2.class create mode 100644 Homework/cs4700/kotlin/lists/MainKt$main$functionList$3.class create mode 100644 Homework/cs4700/kotlin/lists/MainKt.class create mode 100644 Homework/cs4700/kotlin/main.jar create mode 100644 Homework/cs4700/prolog/castle.pl create mode 100644 Homework/cs4700/prolog/test.pl (limited to 'Homework/cs4700') diff --git a/Homework/cs4700/dart/fractal.dart b/Homework/cs4700/dart/fractal.dart new file mode 100644 index 0000000..c075325 --- /dev/null +++ b/Homework/cs4700/dart/fractal.dart @@ -0,0 +1,161 @@ +import 'package:flutter/material.dart'; +import 'dart:math' as math; + +/// Your code should go into the DrawFractal class. + +/// The fractal is drawn as an extension of the CustomPainter. +class DrawFractal extends CustomPainter { + var level = 10; // max level of fractal + + // Constructor that initializes the level of the fractal + DrawFractal(value) { + level = value; + } + + // Recursively draw the fractal + void fractal(Canvas canvas, int level) { + if (level >= this.level) { + return; + } + + final paint = Paint() + ..color = Colors.black + ..strokeWidth = 1; + + // Recursively draw the left branch + canvas.save(); + canvas.rotate(math.pi / 6); + canvas.drawLine(Offset.zero, Offset(50 / level, 50 / level), paint); + canvas.translate(50 / level, 50 / level); + + fractal(canvas, level + 1); + canvas.restore(); + + // As we go up the call stack, draw the right branch + canvas.rotate(-math.pi / 6); + canvas.drawLine(Offset.zero, Offset(50 / level, 50 / level), paint); + canvas.translate(50 / level, 50 / level); + fractal(canvas, level + 1); + } + + /// Called when the canvas is (re)painted, perform the initial moving of the + /// fractal to the center and other actions here such as the initial call to fractal. + @override + void paint(Canvas canvas, Size size) { + fractal(canvas, 1); + } + + /// Always repaint + @override + bool shouldRepaint(CustomPainter oldDelegate) { + return true; + } +} + +// The code before here is to set up the flutter app and run it. You may not have to +// change this code. + +/// Run the application +void main() => runApp(MyApp()); + +/// The application runs a streambuilder widget +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + // The title of my application + title: 'My flutter application', + home: StreamBuilderSetup(), + debugShowCheckedModeBanner: false, + ); + } +} + +/// Stream to generate numbers from 1 to 10 +Stream generateNumbers = (() async* { + await Future.delayed(const Duration(seconds: 2)); + + for (int i = 1; i <= 10; i++) { + await Future.delayed(const Duration(seconds: 1)); + yield i; + } +})(); + +/// Setup a streambuild widget +class StreamBuilderSetup extends StatefulWidget { + @override + State createState() { + return _StreamBuilderSetupState(); + } +} + +/// The innards of the streambuilder widget +class _StreamBuilderSetupState extends State { + /// Boilerplate for initializing the state of the widget + @override + initState() { + super.initState(); + } + + /// Build the widget, it consists of a title and a SizedBox where the + /// drawing of the fractal (but could be anything takes place) + /// Most of this is boilerplate code. + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + // Title bar for the widget + title: const Text('Draw a Fractal in Flutter'), + ), + // Box in which to draw the fractal + body: SizedBox( + width: double.infinity, + child: Center( + child: StreamBuilder( + stream: generateNumbers, + initialData: 0, + builder: ( + BuildContext context, + AsyncSnapshot snapshot, + ) { + if (snapshot.connectionState == ConnectionState.waiting) { + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const CircularProgressIndicator(), + Visibility( + visible: snapshot.hasData, + child: Text( + snapshot.data.toString(), + style: + const TextStyle(color: Colors.black, fontSize: 24), + ), + ), + ], + ); + } else if (snapshot.connectionState == ConnectionState.active || + snapshot.connectionState == ConnectionState.done) { + if (snapshot.hasError) { + return const Text('Error'); + } else if (snapshot.hasData) { + return Center( + child: CustomPaint( + // Set up a canvas of size 500 by 5000 + size: const Size(500, 500), + // Draw the fractal passing the level from the stream + painter: DrawFractal(snapshot.data)), + ); + } else { + return const Text('Empty data'); + } + } else { + return Text('State: ${snapshot.connectionState}'); + } + }, + ), + ), + ), + ); + } +} diff --git a/Homework/cs4700/dart/streams.dart b/Homework/cs4700/dart/streams.dart new file mode 100644 index 0000000..b7d7b26 --- /dev/null +++ b/Homework/cs4700/dart/streams.dart @@ -0,0 +1,106 @@ +import 'dart:io'; + +// Generates a stream of n fibonacci numbers, sleeping 1 second every iteration +Stream Function() fibonnaciNumbers(int n) { + final Stream Function() func = (() async* { + var x = 0, y = 1; + for (int i = 0; i <= n; i++) { + yield x; + sleep(new Duration(seconds: 1)); + y += x; + x = y - x; + } + }); + return func; +} + +// Filters a stream of integers with a function predicate determining to each of the elements in the stream. +Stream Function() streamFilter(Stream stream, bool Function(int) f) { + final Stream Function() func = (() async* { + await for (var i in stream) { + if (f(i)) { + yield i; + } + } + }); + return func; +} + +// Iterates over a stream, accumulatively applying a binary function to a stream of integers until the last +// element and returns the accumulation. +Stream Function() streamAccumulation( + Stream stream, int Function(int, int) f, initial) { + final Stream Function() func = (() async* { + int a = initial; + await for (var i in stream) { + a = f(a, i); + yield a; + } + }); + return func; +} + +Stream Function() generateNumbers(int n) { + final Stream Function() func = (() async* { + for (int i = 1; i <= n; i++) { + await Future.delayed(const Duration(seconds: 1)); + yield i; + } + }); + return func; +} + +// Given a list of lists, returns a list containing all the non-null elements of each list into a single list +List? flatten(List? aList) { + if (aList == null) return null; + return aList + .where((i) => i != null) + .expand((i) => i!) + .where((i) => i != null) + .toList(); +} + +// Generates a nested list where each element's index i is in a sublist of depth i+1. +// For example, deepen([1,2,3]) => [1, [2, [3]]] +List? deepen(List? aList) { + if (aList == null) return null; + return aList.reversed + .fold([], (a, x) => (a != null && a.isEmpty) ? [x] : [x, a]); +} + +void main(List arguments) async { + print('flattening [[0,1], [2]] yields ${flatten([ + [0, 1], + [2] + ])}'); + print('flattening [[0,1], [2], null] yields ${flatten([ + [0, 1], + [2], + null + ])}'); + print('flattening [[0,1, null], [2]] yields ${flatten([ + [0, 1, null], + [2] + ])}'); + print('flattening null yields ${flatten(null)}'); + print('flattening [null] yields ${flatten([null])}'); + print('deepening [0,1,2] yields ${deepen([0, 1, 2])}'); + print('deepening [0,null,2] yields ${deepen([0, null, 2])}'); + print('deepening [0] yields ${deepen([0])}'); + print('deepening [] yields ${deepen([])}'); + print('deepening null yields ${deepen(null)}'); + await for (final number in fibonnaciNumbers(7)()) { + print('fibonnaci number is ${number}'); + } + await for (final number in streamFilter(generateNumbers(10)(), ((a) { + return a % 2 == 0; + }))()) { + print('filtered number is $number'); + } + + await for (final number in streamAccumulation(generateNumbers(10)(), ((a, b) { + return a + b; + }), 0)()) { + print('cumulative number is $number.'); + } +} diff --git a/Homework/cs4700/kotlin/Lists.kt b/Homework/cs4700/kotlin/Lists.kt new file mode 100644 index 0000000..2839b8c --- /dev/null +++ b/Homework/cs4700/kotlin/Lists.kt @@ -0,0 +1,154 @@ +// Do not remove or rename the package +package lists + +/* +* The following functions are helper functions that I am providing +*/ + +/* +* Extend the List class with a "tail" getter to get the tail of a list. +* Below is an example of how you would use tail +* val a = listOf(1,2,3) +* val t = a.tail +* println("tail of $a is $t") // prints [2,3] +*/ +val List.tail: List +get() = drop(1) + +/* +* Extend the List class with a "head" getter to get the head of a list. +* Below is an example of how you would use head +* val a = listOf(1,2,3) +* val h = a.head +* println("head of $a is $h") // prints 1 +*/ +val List.head: T +get() = first() + +/* +* The isPrime function takes as input an Int +* x : an Int object to test +* and returns a Boolean +* true if x is a prime +* false if x is not a prime +*/ +fun isPrime(x : Int) : Boolean { + if (x == 1) + return false + for (i in 2..(x-1)) { + if (x % i == 0) { + return false + } + } + return true +} + +/* The compose function takes as input +* f - A function that takes as input a value of type T and returns a value of type T +* g - A function that takes as input a value of type T and returns a value of type T +* and returns as output the composition of the functions +* f(g(x)) +*/ +fun compose(f: (T)->T, g:(T) -> T) : (T) -> T = { f(g(it)) } + +/* Be sure to document + your functions + describing inputs and outputs and what the function does + */ + +/** + * @param limit is the upper bound of the list of natural numbers + * @return a list of natural numbers up to limit + */ +fun countingNumbers(limit : Int?) : List? { + if (limit == null) + return null + return (1..limit).map { it } +} + +/** + * @param limit is the upper bound of the list of even numbers + * @return a list of even numbers up to limit + */ +fun evenNumbers(limit : Int?) : List? { + return countingNumbers(limit)?.filter( { it % 2 == 0 } ) +} + +/** + * @param limit is the upper bound of the list of prime numbers + * @return a list of prime numbers up to limit + */ +fun primeNumbers(limit : Int?) : List? { + return countingNumbers(limit)?.filter( { isPrime(it) } ) +} + +/** + * @param a is a null-safe list of elements of "Comparable" items + * @param b is a null-safe list of elements of "Comparable" items + * @return a sorted merge list of the elements of a and b + */ +fun> merge(a: List?, b: List?) : List? { + if (a == null || b == null) + return null + + val merged = mutableListOf() + + var aInd = 0 + var bInd = 0 + + while (aInd < a.size && bInd < b.size) { + if (a[aInd] < b[bInd]) { + merged.add(a[aInd]); + aInd++; + continue; + } + merged.add(b[bInd]); + bInd++; + } + + if (aInd < a.size) + merged += a.subList(aInd, a.size) + + else if (bInd < b.size) + merged += b.subList(bInd, b.size) + + return merged +} + +/** + * @param a is a null-safe list of elements + * @return a list of "sublists" where result[i] = a[0..i] + */ +fun subLists(a: List?) : List>? { + if (a == null) + return null + return (1..(a.size)).map( { a.subList(0, it) } ) +} + +/** + * @param a is a null-safe list of lists of elements + * @return the number of elements total in each sublist + */ +fun countElements(a: List? >?) : Int? { + if (a == null) + return a + return a.filter({ it != null }).fold(0, { acc, x -> acc + x!!.size }) +} + +/** + * @param a is a null-safe list of lists of elements + * @return the number of elements total in each sublist + */ +fun listApply(f: (T, T) -> T, a: List>?): List? { + if (a == null) + return null + return a.map( { l: List -> l.foldIndexed( l[0], { index, acc, arg -> if (index > 0) f(acc, arg) else arg } ) } ); +} + +/** + * @param a is a list of functions + * @return a function that the composition of the list of functions (from right to left) + */ +fun composeList(a: List<(T) -> T>): (T) -> T { + return a.foldRight({ x -> x }, { acc, f: (T) -> T -> { x -> f(acc(x)) } }); +} diff --git a/Homework/cs4700/kotlin/META-INF/main.kotlin_module b/Homework/cs4700/kotlin/META-INF/main.kotlin_module new file mode 100644 index 0000000..49be1bf Binary files /dev/null and b/Homework/cs4700/kotlin/META-INF/main.kotlin_module differ diff --git a/Homework/cs4700/kotlin/Main.kt b/Homework/cs4700/kotlin/Main.kt new file mode 100644 index 0000000..0fafdf5 --- /dev/null +++ b/Homework/cs4700/kotlin/Main.kt @@ -0,0 +1,85 @@ +/** + * The main part of the lists package consists of functions to test the functions you code, you may modify however you like as I will use my own Main.kt to test + */ +package lists + +// Functions for composeList testing +fun add1(x: Int) : Int = x + 1 +fun add2(x: Int) : Int = x + 2 + +// Functions for listApply testing +fun add(x : Int, y : Int) : Int { + return x + y +} + +fun main(args: Array) { + println("Start testing") + // Comment out tests you don't use + /* This is a multi-line + comment + */ + val n = 12 + val zero = 0 + val nAsNull = null + + // countingNumbers tests + val countingNumbersUpToN = countingNumbers(n) + println("countingNumbers to $n are $countingNumbersUpToN") + val countingNumbersZero = countingNumbers(zero) + println("countingNumbers to $zero are $countingNumbersZero") + val countingNumbersNull = countingNumbers(nAsNull) + println("countingNumbers to $nAsNull are $countingNumbersNull") + println() + + // evenNumbers tests + val evenNumbersUpToN = evenNumbers(n) + println("evenNumbers to $n are $evenNumbersUpToN") + val evenNumbersZero = evenNumbers(zero) + println("evenNumbers to $zero are $evenNumbersZero") + val evenNumbersNull = evenNumbers(nAsNull) + println("evenNumbers to $nAsNull are $evenNumbersNull") + println() + + // primeNumbers tests + val primesUpToN = primeNumbers(n) + println("primeNumbers to $n are $primesUpToN") + val primesUpToZero = primeNumbers(zero) + println("primeNumbers to $zero are $primesUpToZero") + val primeNumbersNull = primeNumbers(nAsNull) + println("primeNumbers to $nAsNull are $primeNumbersNull") + println() + + // subLists tests + println("subLists of $primesUpToN are ${subLists(primesUpToN)}") + println("subLists of $evenNumbersZero are ${subLists(evenNumbersZero)}") + println("subLists of $evenNumbersNull are ${subLists(evenNumbersNull)}") + println() + + // countElements tests + println("countElements of subLists of $primesUpToN are ${countElements(subLists(primesUpToN))}") + println("countElements of subLists of even numbers to $zero are ${countElements(subLists(evenNumbersZero))}") + println("countElements of subLists of prime numbers to $nAsNull are ${countElements(subLists(primeNumbersNull))}") + val tempList = listOf(evenNumbersUpToN,evenNumbersZero,evenNumbersNull) + println("countElements of $tempList is ${countElements(tempList)}") + println() + + // merge tests + println("merge of $primesUpToN and $countingNumbersUpToN is ${merge(primesUpToN,countingNumbersUpToN)}") + println("merge of $primesUpToN and $countingNumbersZero is ${merge(primesUpToN,countingNumbersZero)}") + println("merge of $primesUpToN and $countingNumbersNull is ${merge(primesUpToN,countingNumbersNull)}") + println() + + // listApply tests + println("listApply of ::add to $countingNumbersUpToN is ${listApply(::add,subLists(countingNumbersUpToN))}") + println("listApply of ::add to $countingNumbersZero is ${listApply(::add,subLists(countingNumbersZero))}") + println("listApply of ::add to $countingNumbersNull is ${listApply(::add,subLists(countingNumbersNull))}") + println() + + // composeList test + val functionList = listOf(::add1,::add2,::add1) + val composedFunction = composeList(functionList) + var result = composedFunction(n) + println("composedFunction of [::add1,::add2,::add1] applied to $n is $result") + +} + diff --git a/Homework/cs4700/kotlin/lists.jar b/Homework/cs4700/kotlin/lists.jar new file mode 100644 index 0000000..dcfdc9c Binary files /dev/null and b/Homework/cs4700/kotlin/lists.jar differ diff --git a/Homework/cs4700/kotlin/lists/ListsKt$compose$1.class b/Homework/cs4700/kotlin/lists/ListsKt$compose$1.class new file mode 100644 index 0000000..fdb4c14 Binary files /dev/null and b/Homework/cs4700/kotlin/lists/ListsKt$compose$1.class differ diff --git a/Homework/cs4700/kotlin/lists/ListsKt$composeList$1.class b/Homework/cs4700/kotlin/lists/ListsKt$composeList$1.class new file mode 100644 index 0000000..aa16793 Binary files /dev/null and b/Homework/cs4700/kotlin/lists/ListsKt$composeList$1.class differ diff --git a/Homework/cs4700/kotlin/lists/ListsKt$composeList$2$1.class b/Homework/cs4700/kotlin/lists/ListsKt$composeList$2$1.class new file mode 100644 index 0000000..8847d9b Binary files /dev/null and b/Homework/cs4700/kotlin/lists/ListsKt$composeList$2$1.class differ diff --git a/Homework/cs4700/kotlin/lists/ListsKt$main$1.class b/Homework/cs4700/kotlin/lists/ListsKt$main$1.class new file mode 100644 index 0000000..9771e62 Binary files /dev/null and b/Homework/cs4700/kotlin/lists/ListsKt$main$1.class differ diff --git a/Homework/cs4700/kotlin/lists/ListsKt$main$f$1.class b/Homework/cs4700/kotlin/lists/ListsKt$main$f$1.class new file mode 100644 index 0000000..23c2833 Binary files /dev/null and b/Homework/cs4700/kotlin/lists/ListsKt$main$f$1.class differ diff --git a/Homework/cs4700/kotlin/lists/ListsKt$main$f$2.class b/Homework/cs4700/kotlin/lists/ListsKt$main$f$2.class new file mode 100644 index 0000000..1e1ac49 Binary files /dev/null and b/Homework/cs4700/kotlin/lists/ListsKt$main$f$2.class differ diff --git a/Homework/cs4700/kotlin/lists/ListsKt.class b/Homework/cs4700/kotlin/lists/ListsKt.class new file mode 100644 index 0000000..a31cea6 Binary files /dev/null and b/Homework/cs4700/kotlin/lists/ListsKt.class differ diff --git a/Homework/cs4700/kotlin/lists/MainKt$main$1.class b/Homework/cs4700/kotlin/lists/MainKt$main$1.class new file mode 100644 index 0000000..2197f8f Binary files /dev/null and b/Homework/cs4700/kotlin/lists/MainKt$main$1.class differ diff --git a/Homework/cs4700/kotlin/lists/MainKt$main$2.class b/Homework/cs4700/kotlin/lists/MainKt$main$2.class new file mode 100644 index 0000000..3dbb957 Binary files /dev/null and b/Homework/cs4700/kotlin/lists/MainKt$main$2.class differ diff --git a/Homework/cs4700/kotlin/lists/MainKt$main$3.class b/Homework/cs4700/kotlin/lists/MainKt$main$3.class new file mode 100644 index 0000000..5936baf Binary files /dev/null and b/Homework/cs4700/kotlin/lists/MainKt$main$3.class differ diff --git a/Homework/cs4700/kotlin/lists/MainKt$main$functionList$1.class b/Homework/cs4700/kotlin/lists/MainKt$main$functionList$1.class new file mode 100644 index 0000000..b3c4244 Binary files /dev/null and b/Homework/cs4700/kotlin/lists/MainKt$main$functionList$1.class differ diff --git a/Homework/cs4700/kotlin/lists/MainKt$main$functionList$2.class b/Homework/cs4700/kotlin/lists/MainKt$main$functionList$2.class new file mode 100644 index 0000000..8b0602a Binary files /dev/null and b/Homework/cs4700/kotlin/lists/MainKt$main$functionList$2.class differ diff --git a/Homework/cs4700/kotlin/lists/MainKt$main$functionList$3.class b/Homework/cs4700/kotlin/lists/MainKt$main$functionList$3.class new file mode 100644 index 0000000..4e4dfc0 Binary files /dev/null and b/Homework/cs4700/kotlin/lists/MainKt$main$functionList$3.class differ diff --git a/Homework/cs4700/kotlin/lists/MainKt.class b/Homework/cs4700/kotlin/lists/MainKt.class new file mode 100644 index 0000000..3989e42 Binary files /dev/null and b/Homework/cs4700/kotlin/lists/MainKt.class differ diff --git a/Homework/cs4700/kotlin/main.jar b/Homework/cs4700/kotlin/main.jar new file mode 100644 index 0000000..96faa22 Binary files /dev/null and b/Homework/cs4700/kotlin/main.jar differ diff --git a/Homework/cs4700/prolog/castle.pl b/Homework/cs4700/prolog/castle.pl new file mode 100644 index 0000000..2fa5608 --- /dev/null +++ b/Homework/cs4700/prolog/castle.pl @@ -0,0 +1,97 @@ +% First castle for testing +% The castle is a set of room facts of the form +% room(Castle, FromRoom, ToRoom, cost). +room(dunstanburgh, enter, foyer, 1). +room(dunstanburgh, foyer, livingRoom, 1). +room(dunstanburgh, foyer, hall, 2). +room(dunstanburgh, hall, kitchen, 4). +room(dunstanburgh, hall, garage, 3). +room(dunstanburgh, kitchen, exit, 1). + +% Second castle for testing +room(windsor, enter, foyer, 1). +room(windsor, foyer, hall, 2). +room(windsor, foyer, dungeon, 1). +room(windsor, hall, throne, 1). +room(windsor, hall, stairs, 4). +room(windsor, stairs, dungeon, 3). +room(windsor, throne, stairs, 1). +room(windsor, dungeon, escape, 5). +room(windsor, escape, exit, 1). + +% Third castle for testing +room(alnwick, enter, foyer, 1). +room(alnwick, foyer, hall, 2). +room(alnwick, hall, throne, 1). +room(alnwick, hall, stairs, 4). +room(alnwick, stairs, dungeon, 3). +room(alnwick, dungeon, foundry, 5). +room(alnwick, foyer, passage, 1). +room(alnwick, passage, foundry, 1). +room(alnwick, foundry, exit, 4). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%helper code that generates permutations +%https://stackoverflow.com/questions/9134380/how-to-access-list-permutations-in-prolog +takeout(X,[X|R],R). +takeout(X,[F |R],[F|S]) :- + takeout(X,R,S). + +perm([X|Y],Z) :- + perm(Y,W), + takeout(X,Z,W). +perm([],[]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%printList(list) +% print each element of list on a new line +printList([]). +printList([X | XS]) :- + print(X), + nl, + printList(XS). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%reachable(Castle, AtRoom, GoalRoom, Path, Cost). +% reachable in Castle at AtRoom is true if there exists a path to GoalRoom +% has book keeping to keep track of the path followed and it's cost +reachable(_, Room, Room, [], 0). + +reachable(Castle, AtRoom, GoalRoom, [AtRoom | NextPath], Cost):- + room(Castle, AtRoom, NextRoom, ThisCost), + reachable(Castle, NextRoom, GoalRoom, NextPath, NextCost), + Cost is NextCost + ThisCost. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%tour(Castle, AtRoom, Rooms, Tour) +% tour in Castle is true if there exists a tour from AtRoom that visits +% each room in Rooms in order and then exits the castle +% has book keeping to collect the paths to each room in Rooms + +tour(Castle, AtRoom, [], Path):- + reachable(Castle, AtRoom, exit, Path, _). + +tour(Castle, AtRoom, [VisitRoom | RestRooms], [Path | RestTour]):- + reachable(Castle, AtRoom, VisitRoom, Path, _), + tour(Castle, VisitRoom, RestRooms, RestTour). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%solveRooms(Castle, Rooms). +% solve Rooms is true if there exists a tour that includes the rooms +% in any order +solveRooms(Castle, Rooms):- + perm(Rooms, PermutedRooms), + tour(Castle, enter, PermutedRooms, Path), + flatten(Path, FlattenedPath), + printList(FlattenedPath). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%solveRoomsWithinCost(Castle, Cost) +% Attempts to find a tour from enter to exit +% within Cost, and if found, prints it! +solveRoomsWithinCost(Castle, Cost):- + reachable(Castle, enter, exit, Path, TourCost), + Cost >= TourCost, + flatten(Path, FlattenedPath), + format("Total Cost is ~a out of limit ~a~n", [TourCost, Cost]), + printList(FlattenedPath). diff --git a/Homework/cs4700/prolog/test.pl b/Homework/cs4700/prolog/test.pl new file mode 100644 index 0000000..84fdf61 --- /dev/null +++ b/Homework/cs4700/prolog/test.pl @@ -0,0 +1,51 @@ +% First castle for testing +% The castle is a set of room facts of the form +% room(Castle, FromRoom, ToRoom, cost). +room(dunstanburgh, enter, foyer, 1). +room(dunstanburgh, foyer, livingRoom, 1). +room(dunstanburgh, foyer, hall, 2). +room(dunstanburgh, hall, kitchen, 4). +room(dunstanburgh, hall, garage, 3). +room(dunstanburgh, kitchen, exit, 1). + +% Second castle for testing +room(windsor, enter, foyer, 1). +room(windsor, foyer, hall, 2). +room(windsor, foyer, dungeon, 1). +room(windsor, hall, throne, 1). +room(windsor, hall, stairs, 4). +room(windsor, stairs, dungeon, 3). +room(windsor, throne, stairs, 1). +room(windsor, dungeon, escape, 5). +room(windsor, escape, exit, 1). + +% Third castle for testing +room(alnwick, enter, foyer, 1). +room(alnwick, foyer, hall, 2). +room(alnwick, hall, throne, 1). +room(alnwick, hall, stairs, 4). +room(alnwick, stairs, dungeon, 3). +room(alnwick, dungeon, foundry, 5). +room(alnwick, foyer, passage, 1). +room(alnwick, passage, foundry, 1). +room(alnwick, foundry, exit, 4). + +test1() :- writeln('solveRoomsWithinCost(dunstanburgh, 8)'), + solveRoomsWithinCost(dunstanburgh, 8). +test2() :- writeln('solveRoomsWithinCost(windsor, 13)'), + solveRoomsWithinCost(windsor, 13). +test3() :- writeln('solveRoomsWithinCost(alnwick, 15)'), + solveRoomsWithinCost(alnwick, 15). +test4() :- writeln('solveRooms(dunstanburgh, [foyer, kitchen])'), + solveRooms(dunstanburgh, [foyer, kitchen]). +test5() :- writeln('solveRooms(windsor, [stairs])'), + solveRooms(windsor, [stairs]). +test6() :- writeln('solveRooms(alnwick, [foyer, hall])'), + solveRooms(alnwick, [foyer, hall]). +test7() :- writeln('solveRooms(alnwick, [foyer, passage])'), + solveRooms(alnwick, [foyer, passage]). +test8() :- writeln('fails: solveRooms(alnwick, [foyer, throne, escape])'), + solveRooms(alnwick, [foyer, throne, passage]). +test9() :- writeln('fails: solveRoomsWithinCost(alnwick, 4)'), + solveRoomsWithinCost(alnwick, 4). + -- cgit v1.3