Skip to content

Instantly share code, notes, and snippets.

@mizuhara
Created September 17, 2018 09:58
Show Gist options
  • Save mizuhara/75f8e10b655c3702b37ccf5c240713e2 to your computer and use it in GitHub Desktop.
Save mizuhara/75f8e10b655c3702b37ccf5c240713e2 to your computer and use it in GitHub Desktop.
using System;
using System.Linq;
namespace yhpg
{
internal enum Direction
{
Up = 0, Down, Left, Right, None
}
internal interface IMass
{
Direction NextDirection(Direction direction);
}
internal class Dot : IMass
{
public Direction NextDirection(Direction direction)
{
return direction;
}
}
internal class Zero : IMass
{
public Direction NextDirection(Direction direction)
{
switch (direction)
{
default:
return Direction.None;
case Direction.Up:
return Direction.Left;
case Direction.Down:
return Direction.Right;
case Direction.Left:
return Direction.Up;
case Direction.Right:
return Direction.Down;
}
}
}
internal class One : IMass
{
public Direction NextDirection(Direction direction)
{
switch (direction)
{
default:
return Direction.None;
case Direction.Up:
return Direction.Right;
case Direction.Down:
return Direction.Left;
case Direction.Left:
return Direction.Down;
case Direction.Right:
return Direction.Up;
}
}
}
internal class X : IMass
{
public Direction NextDirection(Direction direction)
{
return Direction.None;
}
}
internal class MassFactory
{
public static IMass Create(char symbol)
{
switch (symbol)
{
default:
throw new ArgumentException("不正な記号");
case 'Y':
case '.':
return new Dot();
case '0':
return new Zero();
case '1':
return new One();
case 'x':
return new X();
}
}
}
internal struct Position
{
public int x;
public int y;
public Position(int x, int y)
{
this.x = x;
this.y = y;
}
}
internal class Field
{
private readonly int width;
private readonly int height;
private readonly string[] src;
private readonly string alphabets;
public Field(string src)
{
this.src = src.Split(new char[] { '/' });
width = this.src[0].Length;
height = this.src.Length;
var ary =
Enumerable
.Range(0, width * height)
.Select(e => (char)('a' + e))
.ToArray();
alphabets = String.Join(String.Empty, ary);
}
public Position StartPosition()
{
var pos = String.Join(String.Empty, src).IndexOf('Y');
var x = pos % width;
var y = pos / height;
return new Position(x, y);
}
public string AlphabetAt(Position position)
{
if (IsOut(position))
{
return String.Empty;
}
var x = position.x;
var y = position.y;
return alphabets.Substring(y * height + x, 1);
}
public Position NextPosition(Position position, Direction direction)
{
switch (direction)
{
default:
throw new ArgumentException("不正な方向");
case Direction.Up:
return new Position(position.x, position.y - 1);
case Direction.Down:
return new Position(position.x, position.y + 1);
case Direction.Left:
return new Position(position.x - 1, position.y);
case Direction.Right:
return new Position(position.x + 1, position.y);
}
}
public Direction NextDirection(Position position, Direction direction)
{
if (IsOut(position))
{
return Direction.None;
}
var x = position.x;
var y = position.y;
var nextMass = MassFactory.Create(src[y][x]);
return nextMass.NextDirection(direction);
}
public bool CanPassThrough(Position position)
{
if (IsOut(position))
{
return false;
}
var x = position.x;
var y = position.y;
return !src[y][x].Equals("x");
}
public int Size()
{
return width * height;
}
private bool IsOut(Position position)
{
var x = position.x;
var y = position.y;
return (x < 0) || (width <= x) || (y < 0) || (height <= y);
}
}
internal class Light
{
private Position curPosition;
private Direction curDirection;
public Light(Position curPosition, Direction curDirection = Direction.Up)
{
this.curPosition = curPosition;
this.curDirection = curDirection;
}
public string Trajectory { get; private set; }
public void PassThrough(Field field)
{
Trajectory += field.AlphabetAt(curPosition);
PassThroughRecursive(field);
var res = Trajectory.ToCharArray().Distinct().ToArray();
Array.Sort(res);
Trajectory = string.Join(String.Empty, res);
}
private void PassThroughRecursive(Field field)
{
curPosition = field.NextPosition(curPosition, curDirection);
curDirection = field.NextDirection(curPosition, curDirection);
if (curDirection.Equals(Direction.None))
{
return;
}
if (!field.CanPassThrough(curPosition))
{
return;
}
if (field.Size() <= Trajectory.Length)
{
return;
}
Trajectory += field.AlphabetAt(curPosition);
PassThroughRecursive(field);
}
}
class MainClass
{
public static void Main(string[] args)
{
/*0*/
Test("x...x/.1.0./..0../.Y.../0..x.", "ghilnqs");
/*1*/
Test("..Y../...../...../...../.....", "c");
/*2*/
Test("..x../..Y../...../...../.....", "h");
/*3*/
Test("..Y.x/..1x0/11.../....0/1..1.", "c");
/*4*/
Test("....1/....Y/...../...../.....", "ej");
/*5*/
Test(".10../x.1../x.1x./.Y.1./...0.", "bcghlq");
/*6*/
Test("0.x10/00..x/x0x.0/....0/...Y1", "deinsx");
/*7*/
Test("1.01./01Y.1/..1.1/..10./0.0..", "abcfgh");
/*8*/
Test("x..../x1x../0...0/....Y/.1..0", "klmnot");
/*9*/
Test("...../..10./.1Y1./.01../.....", "hilmnqr");
/*10*/
Test("...../..10./x.11./...../..Y..", "hilmnrw");
/*11*/
Test("...../x.10x/...../x.Y1x/.....", "himnqrs");
/*12*/
Test("..010/...Y1/..0../0.x../.....", "defghij");
/*13*/
Test("1.0../...../.0x../Y.1x./..1..", "abcfhkp");
/*14*/
Test("...../101../0.0../..Y../.....", "fgklmqrv");
/*15*/
Test("1.0../00.../.x..0/0.Y1./...10", "abcfghmr");
/*16*/
Test("x101./1..../.Y.x./..01./.00.1", "bcghlmrs");
/*17*/
Test("x11../x.x../.0.01/..x../...Y.", "bcglmnsx");
/*18*/
Test("..1.0/x0.x./0.0../x...Y/.10.1", "cdehjmnot");
/*19*/
Test("..x.0/.0.../1..0x/1..1./Y.00.", "klmnpqrsu");
/*20*/
Test("0.1.0/.0.xY/0...0/01..1/x00.x", "cdehjmrwx");
/*21*/
Test("...0./.0.0./..101/...10/..01Y", "mnpqrstwxy");
/*22*/
Test("10..0/.Y.0./0..1./....x/000..", "abfghiklmn");
/*23*/
Test("10..1/...../.1010/110.1/x..Yx", "lmnopqrstx");
/*24*/
Test("110../....1/x1..x/0.0.0/....Y", "bcghlmrsty");
/*25*/
Test("x.101/1..../..001/010Yx/..1.1", "cdehijmnos");
/*26*/
Test("x.111/x10../...0./00.1x/x.Y.1", "ghklmnqrsw");
/*27*/
Test("11.../....0/11..1/1.1../.Y..1", "fghijlmnoqv");
/*28*/
Test("...x1/.1.0./11.1./.01../Y..x.", "cghiklmnpqru");
/*29*/
Test(".0.../110x./11..0/01.x./..Y.x", "ghklmnopqrtw");
/*30*/
Test(".01.0/.110x/0...0/.01Y./x.1x.", "cdeghilmnqrs");
/*31*/
Test(".1100/..1.0/1.11Y/0..1./.0..0", "hijklmnopqrs");
/*32*/
Test("1..00/..11./.100./1..Y1/.....", "abcdfhikmnps");
/*33*/
Test("1.0../.11x0/.00.x/Y.10./.10x0", "abcfghklmpqr");
/*34*/
Test("11110/11.../.x.../.0111/0.Y0.", "deijnorstwxy");
/*35*/
Test("...1./.1.0x/10..0/0Y.11/.0.x0", "ghiklmnopqrst");
/*36*/
Test("...10/x111./0x.11/.0.../0.0Y.", "dehijmnorswxy");
/*37*/
Test(".1x../.x1.0/0x.x./x11.1/x0Y.1", "hijmoqrstvwxy");
/*38*/
Test("x.x../x110./1.1.0/0.Y.1/0.00x", "hiklmnopqrstx");
/*39*/
Test("...0./11.00/10..x/..0.1/Y0.10", "ghiklmnpqsuvwx");
/*40*/
Test(".110./....0/x..../.0001/11.Y.", "cdfghijmnorstx");
/*41*/
Test("1.00./....1/.1.../0...0/0..1Y", "abcfhkmpqrstwy");
/*42*/
Test(".1.01/..x../..100/..Y../...01", "bcdgilmnoqrstvxy");
/*43*/
Test("1...0/Y..../...../...../0...1", "abcdefjkoptuvwxy");
/*44*/
Test("x1..0/1..0./.Yx../0...1/.0.1.", "bcdefghijklnopqrstvwx");
/*45*/
Test("1...0/.1.0./..1../..01./Y0..1", "abcdefghijklmnopqrstuvwxy");
}
private static void Test(string src, string expected)
{
try
{
var field = new Field(src);
var startPosition = field.StartPosition();
var light = new Light(startPosition);
light.PassThrough(field);
var actual = light.Trajectory;
if (!actual.Equals(expected))
{
Console.WriteLine(
"actual={0}, expected={1}",
actual, expected);
}
}
catch (ArgumentException e)
{
Console.WriteLine(e.Message);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment