Skip to content

Instantly share code, notes, and snippets.

@deanbot
Last active December 12, 2020 23:56
Show Gist options
  • Save deanbot/ab210cbaecabd8232fd9d64b24aab6fe to your computer and use it in GitHub Desktop.
Save deanbot/ab210cbaecabd8232fd9d64b24aab6fe to your computer and use it in GitHub Desktop.
Advent Of Code 2020 Day 12 in dart
void main() {
final List<Object> solutions = [
SolutionA(),
SolutionB()
];
solutions.forEach((s) => print(s.toString()));
}
// Full inputs at https://adventofcode.com/2020/day/12/input
const inputsDay12 = """F10
N3
F7
R90
F11""";
enum Action { N, S, E, W, L, R, F }
var charAction = {
'N': Action.N,
'S': Action.S,
'E': Action.E,
'W': Action.W,
'L': Action.L,
'R': Action.R,
'F': Action.F
};
List<Instruction> _parseInputs(String inputs) => inputs
.split('\n')
.where((element) => element.isNotEmpty)
.map((e) => Instruction.fromString(e))
.toList();
var _inputs = _parseInputs(inputsDay12);
class Instruction {
final Action action;
final int distance;
Instruction.fromString(String input)
: action = charAction[input.split('')[0]],
distance = int.parse(input.split('').skip(1).join(''));
@override
String toString() => "$action$distance";
}
enum Direction {
N,
S,
E,
W,
}
var directions = [Direction.N, Direction.E, Direction.S, Direction.W];
var actionDirection = {
Action.N: Direction.N,
Action.E: Direction.E,
Action.S: Direction.S,
Action.W: Direction.W
};
enum ShipVersion { One, Two }
class Ship {
final shipVersion;
int _x = 0;
int _y = 0;
Direction direction;
int _rX = 10;
int _rY = 1;
Ship({this.shipVersion = ShipVersion.Two}) : direction = Direction.E;
instruct(Instruction instruction) {
Direction moveDirection;
Action action = instruction.action;
int distanceOrDegree = instruction.distance;
if (shipVersion == ShipVersion.One) {
if (action == Action.R || action == Action.L) {
turn(distanceOrDegree, isLeft: action == Action.L);
} else {
if (action != Action.F) {
moveDirection = actionDirection[action];
}
move(distanceOrDegree, moveDirection);
}
} else if (shipVersion == ShipVersion.Two) {
if (action == Action.R || action == Action.L) {
rotate(distanceOrDegree, isLeft: action == Action.L);
} else {
if (action == Action.F) {
move(distanceOrDegree * _rX, _rX >= 0 ? Direction.E : Direction.W);
move(distanceOrDegree * _rY, _rY >= 0 ? Direction.N : Direction.S);
} else {
moveDirection = actionDirection[action];
moveWaypoint(distanceOrDegree, moveDirection);
}
}
}
// print(this.toString());
}
rotate(int degree, {isLeft = false}) {
var deg = (360 + (isLeft ? -degree : degree)) % 360;
var prevRX = _rX;
var prevRY = _rY;
if (deg == 90 || deg == 270) {
_rX = prevRY;
_rY = prevRX;
}
if (deg == 90) {
_rY = -_rY;
} else if (deg == 180) {
_rX = -_rX;
_rY = -_rY;
} else if (deg == 270) {
_rX = -_rX;
}
}
turn(int degree, {isLeft = false}) {
var index = directions.indexOf(direction), inc = degree ~/ 90;
index += inc * (isLeft ? -1 : 1);
index = index % directions.length;
direction = directions[index];
}
moveWaypoint(int instructionDistance, Direction instructionDirection) {
var dir = instructionDirection != null ? instructionDirection : direction;
switch (dir) {
case Direction.N:
_rY += instructionDistance;
break;
case Direction.S:
_rY -= instructionDistance;
break;
case Direction.E:
_rX += instructionDistance;
break;
case Direction.W:
_rX -= instructionDistance;
break;
}
}
move(int instructionDistance, Direction instructionDirection) {
var dir = instructionDirection != null ? instructionDirection : direction;
switch (dir) {
case Direction.N:
case Direction.S:
_y += instructionDistance;
break;
case Direction.E:
case Direction.W:
_x += instructionDistance;
break;
}
}
get absX => _x < 0 ? -_x : _x;
get absY => _y < 0 ? -_y : _y;
get absRX => _rX < 0 ? -_rX : _rX;
get absRY => _rY < 0 ? -_rY : _rY;
@override
String toString() => "${_x >= 0 ? 'east' : 'west'} $absX,"
" ${_y >= 0 ? 'north' : 'south'} $absY"
" -> $direction"
" (WP: ${_rX >= 0 ? 'east' : 'west'} $absRX, ${_rY >= 0 ? 'north' : 'south'} $absRY)";
}
abstract class AdventSolution {
final int day;
final String name;
AdventSolution(this.day, this.name);
// implement in subclass
String getSolution();
@override
String toString() {
return "Advent Of Code, "
"Day $day "
"${name.isNotEmpty ? name : ''} "
"solution: ${getSolution()}";
}
}
abstract class _Day12Solution extends AdventSolution {
_Day12Solution(name) : super(12, name);
}
class SolutionA extends _Day12Solution {
SolutionA() : super('A');
String getSolution() {
var ship = Ship(shipVersion: ShipVersion.One);
_inputs.forEach(ship.instruct);
return (ship.absX + ship.absY).toString();
}
}
class SolutionB extends _Day12Solution {
SolutionB() : super('B');
String getSolution() {
var ship = Ship();
_inputs.forEach(ship.instruct);
return (ship.absX + ship.absY).toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment