nw_wind: (Камлать)
[personal profile] nw_wind
Немного програзма.

Операторы связи часто обмениваются друг с другом интервалами или диапазонами номеров. Например, диапазон это 4167700-4167899. А вот телефонные станции оперируют префиксами. То есть теми частями номера, которые в этом интервале не изменяются, в последующие цифры могут быть любыми. В вышеупомянутом примере это будет два префикса 41677 и 41678. Перелопачивать ручками десятки интервалов не самое интересное занятие, да и вероятность ошибки велика. Находясь в Ла Риохе (Испания) и под винными парами после дегустации замечательных напитков, я написал вот такую прелестную программку.

Кто поймёт как программа работает, тому зачёт. Написал со сторонним эффектом тк здесь он, мне кажется, вполне оправдан. Переменная dmax - это максимальная глубина погружения при поиске префиксов. Это можно вообще убрать. Я поставил тк мне стрёмно поведение рекурсивных алгоритмов с глубиной в десяток порядков.

На вход ей можно дать пары "начало:конец" интервалов с любыми разделителями. На выходе будут префиксы.

Программа распиливает диапазон на наименьшее возможное количество префиксов.

Пользуйтесь на здоровье. Не забывайте хвалить, размещать ссылки, рекомендовать товарищам, упоминать при использовании в ваших продуктах и платить роялти при использовании в продуктах коммерческих. Ибо GPL это.


#!/usr/bin/perl -w

# Sergei Keler (www.keler.net).
# Interval to Prefixes.

use strict;

# На входе пары типа начало:конец построчно
# Разделитель любой, :., таб - и пробел.
# На выходе префиксы.

my @r=(); # массив префиксов исключительно ради сортировки. Можно не использовать.
my $dpt=0;
my $dmax=1000000; # Максимальная глубина поиска.

# Просто читаем пары чисел с любым разделителем.
while (<>) {
  chomp;
  my ($s,$f)=split /[ \t:,.-]/;
  $dpt=0;
  maxint($s,$f); # преобразуем
}
# вывод.
foreach my $p (sort @r) {
  print "$p\n";
}

# Собственно логика тут.
sub maxint {
  my ($s,$f)=@_;
  
  return if $dpt++ > $dmax;
  if ($s == $f) {
    push @r,$s; # Можно print $s;
    return;
  }
  return if ($s > $f);
  if (($s % 10) != 0) {
    push @r,$s; # Можно print $s;
    return maxint($s+1,$f);
  }
  if (($f % 10) != 9) {
    push @r,$f; # Можно print $f;
    return maxint($s,$f-1);
  }
  return maxint(int($s/10), int($f/10));
}

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

June 2017

S M T W T F S
    123
45678910
111213 1415 1617
18192021222324
252627282930 

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Apr. 7th, 2026 04:51 pm
Powered by Dreamwidth Studios