#!/usr/bin/perl -w

# Copyright 2015 Kevin Ryde

# This file is part of Math-PlanePath.
#
# Math-PlanePath is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3, or (at your option) any later
# version.
#
# Math-PlanePath is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along
# with Math-PlanePath.  If not, see <http://www.gnu.org/licenses/>.

use 5.010;
use strict;
use warnings;
use List::MoreUtils;
use POSIX 'floor';
use Math::BaseCnv;
use Math::Libm 'M_PI', 'hypot', 'cbrt';
use List::Util 'min', 'max', 'sum';
use Math::PlanePath::DekkingCurve;
use Math::PlanePath::Base::Digits
  'round_down_pow','digit_split_lowtohigh';
use Math::PlanePath::Base::Generic
  'is_infinite',
  'round_nearest';

# uncomment this to run the ### lines
# use Smart::Comments;


{
  # X leading diagonal segments

  my $path = Math::PlanePath::DekkingCentres->new;
  my @values;
  my $prev = -1;
  foreach my $i (0 .. 500) {
    my $n = $path->xyxy_to_n($i,$i, $i+1,$i+1); # forward
    # my $n = $path->xyxy_to_n($i+1,$i+1, $i,$i); # reverse
    if (defined $n) {
      my $i5 = Math::BaseCnv::cnv($i,10,5);
      print "$i [$i5]  \n";
      push @values, $i;
    }
    $prev = $n;
  }
  require Math::OEIS::Grep;
  Math::OEIS::Grep->search(array => \@values, verbose=>1);
  exit 0;
}

{
  # X negative axis N not increasing

  my $path = Math::PlanePath::DekkingCurve->new (arms => 3);
  my @values;
  my $prev = -1;
  foreach my $i (0 .. 500) {
    my $n = $path->xy_to_n(-$i,0);
    if ($n < $prev) {
      my $i5 = Math::BaseCnv::cnv($i,10,5);
      print "$i [$i5]  \n";
      push @values, $i;
    }
    $prev = $n;
  }
  require Math::OEIS::Grep;
  Math::OEIS::Grep->search(array => \@values, verbose=>1);
  exit 0;
}

{
  # X,Y axis points in common (none)

  my $path = Math::PlanePath::DekkingCurve->new;
  my @values;
  foreach my $i (0 .. 500) {
    my $nx = $path->xy_to_n($i,0);
    my $ny = $path->xy_to_n(0,$i);
    if (defined $nx && defined $ny) {
      my $i5 = Math::BaseCnv::cnv($i,10,5);
      print "$i5  \n";
      push @values, $i;
    }
  }
  require Math::OEIS::Grep;
  Math::OEIS::Grep->search(array => \@values, verbose=>1);
  exit 0;
}

{
  # Y axis points

  my %table = (S => ['W','N','E','S','S'],
               E => ['N','N','E','S','S'],
               N => ['N','N','E','S','W'],
               W => ['W','N','E','S','W']);
  sub yseg_to_side {
    my ($y) = @_;
    my $state = 'W';
    my @digits = digit_split_lowtohigh($y,5);
    foreach my $digit (reverse @digits) {  # high to low
      $state = $table{$state}->[$digit];
    }
    return $state;
  }

  my $path = Math::PlanePath::DekkingCurve->new;
  my @values;
  foreach my $y (0 .. 500) {
    my $path_point_visit = defined($path->xy_to_n(0,$y)) ? 1 : 0;
    my $path_seg_visit = defined($path->xyxy_to_n_either(0,$y, 0,$y+1)) ? 1 : 0;

    my $side = yseg_to_side($y);
    my $prev_side = $y>0 && yseg_to_side($y-1);
    my $htol_visit = ($side eq 'S' || $side eq 'W'
                      || $prev_side eq 'S' || $prev_side eq 'E'
                      ? 1 : 0);
    my $htol_seg_visit = ($side eq 'S' ? 1 : 0);

    my $diff = ($path_seg_visit == $htol_seg_visit ? '' : '  ***');

    my $y5 = Math::BaseCnv::cnv($y,10,5);
    print "$y5  $path_seg_visit ${htol_seg_visit}[$side] $diff\n";

    if (defined $path_seg_visit) {
      push @values, $y;
    }
  }
  require Math::OEIS::Grep;
  Math::OEIS::Grep->search(array => \@values, verbose=>1);
  exit 0;
}

{
  # X axis points

  # X
  # S -> S,S,E,N,W
  # E -> S,S,E,N,N
  # N -> W,S,E,N,N
  # W -> W,N,E,S,W
  my %table = (S => ['S','S','E','N','W'],
               E => ['S','S','E','N','N'],
               N => ['W','S','E','N','N'],
               W => ['W','S','E','N','W']);
  sub x_to_side {
    my ($x) = @_;
    my $state = 'S';
    my @digits = digit_split_lowtohigh($x,5);
    foreach my $digit (reverse @digits) {  # high to low
      $state = $table{$state}->[$digit];
    }
    return $state;
  }

  my $path = Math::PlanePath::DekkingCurve->new;
  my @values;
  foreach my $x (0 .. 500) {
    my $path_point_visit = defined($path->xy_to_n($x,0)) ? 1 : 0;
    my $path_seg_visit = defined($path->xyxy_to_n_either($x,0, $x+1,0)) ? 1 : 0;

    my $side = x_to_side($x);
    my $prev_side = $x>0 && x_to_side($x-1);
    my $htol_visit = ($side eq 'S' || $side eq 'E'
                      || $prev_side eq 'S' || $prev_side eq 'W'
                      ? 1 : 0);
    my $htol_seg_visit = $path->_UNDOCUMENTED__xseg_is_traversed($x);

    my $diff = ($path_seg_visit == $htol_seg_visit ? '' : '  ***');

    my $x5 = Math::BaseCnv::cnv($x,10,5);
    print "$x5  $path_seg_visit ${htol_visit}[$side] $diff\n";

    if (defined $path_seg_visit) {
      push @values, $x;
    }
  }
  require Math::OEIS::Grep;
  Math::OEIS::Grep->search(array => \@values, verbose=>1);
  exit 0;
}
