Created
September 17, 2018 09:58
-
-
Save mizuhara/75f8e10b655c3702b37ccf5c240713e2 to your computer and use it in GitHub Desktop.
An answer of http://nabetani.sakura.ne.jp/hena/orde27ligmir/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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