locked
Summarize a range of phone numbers RRS feed

  • Question

  • I have a range of telephone numbers that I would like to summarize.  I will be getting these numbers from a text file.  For example, the numbers I have are:

    2015551200
    2015551201
    2015551202
    2015551203
    2015551204
    2015551205
    2015551206
    2015551207
    2015551208
    2015551209
    2015551212
    2015551213
    2015551214
    2015551217
    2015551998
    2015551999
    2015552000
    2015552001

    I would summarize these numbers:

    201555120X
    201555121[2-47]
    201555199[89]
    201555200[01]


    I can't wrap my head around how I could script this.  This is my white whale I've been chasing for a while.  Any tips to how you would approach this would be much appreciated.  Thanks in advance.
    Friday, October 10, 2014 9:53 PM

Answers

  • I played with it a bit, and came up with this:

    $TelNums = 
    (@'
    2015551200
    2015551201
    2015551202
    2015551203
    2015551204
    2015551205
    2015551206
    2015551207
    2015551208
    2015551209
    2015551212
    2015551213
    2015551214
    2015551217
    2015551998
    2015551999
    2015552000
    2015552001
    '@) -split "`n" | foreach {$_.trim()}
    
    function get-range
      {
        Begin { $range = $null }
    
        Process {
                  $base = $_ -replace '.$'
                  $idx  = $_[-1]
    
                  Switch -Regex ($range)
                  { 
    
                    "$base\[\d$" {
                                  if ( $idx -eq (1 + $range[-1]) )
                                    { $range += $idx }
                                 }
    
                    "$base\[\d\d$" {
                                     if ( $idx -eq (1 + $range[-1]) )
                                      {$range =  ($range -replace '.$') + "-$idx" }
                                   }
    
                    "$base\[\d-\d$" {
                                      if ( $idx -eq (1 + $range[-1]) )
                                       {$range =  ($range -replace '.$') + $idx }
                                      
                                       else { $range += $idx }
                                    }
    
                    default         {
                                      if ($range) { ($range + ']').replace('[0-9]','x') }
                                      $range = $base + "[$idx"
                                     }
                 }
         }
    
         End { ($range + ']').replace('[0-9]','x') }
    
      }
    
      $TelNums | get-range
    
    201555120x
    201555121[2-47]
    201555199[89]
    201555200[01]
    


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    • Marked as answer by chengle Tuesday, October 14, 2014 1:02 PM
    Saturday, October 11, 2014 3:25 AM

All replies

  • Why?

    -- Bill Stewart [Bill_Stewart]

    Friday, October 10, 2014 11:17 PM
  • mjolinor:
    201555121[2-47] - contains these numbers 2015551212, 2015551213, 2015551214, 2015551217.  The 2-4 includes numbers 2, 3, and 4 and then the 7 as well.
    201555120X - the X is a wildcard, any number 0-9
    201555199[89] - contains 2015551998 and 2015551999


    Bill_Stewart:
    This will eventually go into a phone system.  It is used to summarize dialing patterns from the telephone company.  I will be given a range of a few thousand numbers broken up that need to be summarized this way.  Doing this manually would take a few hours.



    So far I've tried breaking it down into smaller pieces.  I'll first import the text file and sort it.  Then have the first number, increment it, and set that as the next expected number if it was a range.  So in the list I gave, 2015551200 is the first number.  In my foreach loop, I set 2015551200++, or 2015551201 as the next expected in the loop.  If that is the next number, I increment again until I find one that breaks the range.  So I've done this:


    First number: 2015551200, expected next number if it is in sequence: 2015551201
    Next number: 2015551201, it is in sequence, expected next number if it is in sequence: 2015551202
    Next number: 2015551202, it is in sequence, expected next number if it is in sequence: 2015551203
    Next number: 2015551203, it is in sequence, expected next number if it is in sequence: 2015551204
    Next number: 2015551204, it is in sequence, expected next number if it is in sequence: 2015551205
    Next number: 2015551205, it is in sequence, expected next number if it is in sequence: 2015551206
    Next number: 2015551206, it is in sequence, expected next number if it is in sequence: 2015551207
    Next number: 2015551207, it is in sequence, expected next number if it is in sequence: 2015551208
    Next number: 2015551208, it is in sequence, expected next number if it is in sequence: 2015551209
    Next number: 2015551209, it is in sequence, expected next number if it is in sequence: 2015551210
    Next number: 2015551212, it is not in sequence.  Summarize the last sequence.

    The last range went from 2015551200 to 2015551209.  I need that to look like 201555120X.

    Thanks again for your help.

    Saturday, October 11, 2014 2:59 AM
  • Your data partitioning has a mistake.

    This is sequentially incorrect:

    Vote as helpful1
     201555121[2-47] - contains these numbers 2015551212, 2015551213, 2015551214, 2015551217

    It would be a correct temoplate if it were stated like this:

    20155512[12-47] - contains these numbers 2015551212, 2015551213, 2015551214, 2015551217

       


    ¯\_(ツ)_/¯

    Saturday, October 11, 2014 3:10 AM
  • I played with it a bit, and came up with this:

    $TelNums = 
    (@'
    2015551200
    2015551201
    2015551202
    2015551203
    2015551204
    2015551205
    2015551206
    2015551207
    2015551208
    2015551209
    2015551212
    2015551213
    2015551214
    2015551217
    2015551998
    2015551999
    2015552000
    2015552001
    '@) -split "`n" | foreach {$_.trim()}
    
    function get-range
      {
        Begin { $range = $null }
    
        Process {
                  $base = $_ -replace '.$'
                  $idx  = $_[-1]
    
                  Switch -Regex ($range)
                  { 
    
                    "$base\[\d$" {
                                  if ( $idx -eq (1 + $range[-1]) )
                                    { $range += $idx }
                                 }
    
                    "$base\[\d\d$" {
                                     if ( $idx -eq (1 + $range[-1]) )
                                      {$range =  ($range -replace '.$') + "-$idx" }
                                   }
    
                    "$base\[\d-\d$" {
                                      if ( $idx -eq (1 + $range[-1]) )
                                       {$range =  ($range -replace '.$') + $idx }
                                      
                                       else { $range += $idx }
                                    }
    
                    default         {
                                      if ($range) { ($range + ']').replace('[0-9]','x') }
                                      $range = $base + "[$idx"
                                     }
                 }
         }
    
         End { ($range + ']').replace('[0-9]','x') }
    
      }
    
      $TelNums | get-range
    
    201555120x
    201555121[2-47]
    201555199[89]
    201555200[01]
    


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    • Marked as answer by chengle Tuesday, October 14, 2014 1:02 PM
    Saturday, October 11, 2014 3:25 AM
  • This will eventually go into a phone system. It is used to summarize dialing patterns from the telephone company. I will be given a range of a few thousand numbers broken up that need to be summarized this way.

    What does "summarize dialing patterns" mean, and why is such a summary needed?


    -- Bill Stewart [Bill_Stewart]

    Saturday, October 11, 2014 3:48 PM
  • Lets say I have a range of phone numbers of 212-555-0000 through 212-555-9999.  I could put in 1000 individual numbers or I could create a range 212555XXXX.  That summary includes all the numbers without having to create all 1000.  It would be nice if there we owned all 1000 numbers in that range, but we don't.  This will make it so I don't have to create 900 individual dialing patterns, but with wildcards, can create 10-20.
    Sunday, October 12, 2014 4:04 PM
  • Lets say I have a range of phone numbers of 212-555-0000 through 212-555-9999.  I could put in 1000 individual numbers or I could create a range 212555XXXX.  That summary includes all the numbers without having to create all 1000.  It would be nice if there we owned all 1000 numbers in that range, but we don't.  This will make it so I don't have to create 900 individual dialing patterns, but with wildcards, can create 10-20.
    You're off by an order of magnitude.  212555XXXX would span 10,000 numbers.

    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    Sunday, October 12, 2014 4:28 PM
  • Lets say I have a range of phone numbers of 212-555-0000 through 212-555-9999.  I could put in 1000 individual numbers or I could create a range 212555XXXX.  That summary includes all the numbers without having to create all 1000.  It would be nice if there we owned all 1000 numbers in that range, but we don't.  This will make it so I don't have to create 900 individual dialing patterns, but with wildcards, can create 10-20.

    You're off by an order of magnitude.  212555XXXX would span 10,000 numbers.

    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    This was my point earlier.  Your template system does not work as you think you have defined it.  Why don't you just use a standard notaion instead of trying to reinvent the wheel.

    A range is [<start>-<end>] (example:[2001-2999] with a mask of nnn-nnn-XXXX)

    A list is [n,n,n,n...] ( example: [10,20,30,40] with a mask of nnn-nnn-nnXX)

    That is how nearly all PABX systems define templates.


    ¯\_(ツ)_/¯


    • Edited by jrv Sunday, October 12, 2014 4:57 PM
    Sunday, October 12, 2014 4:57 PM
  • This will be going into a Cisco Call Manager and that is how they are summarized. 

    I was off on the magnitude, you are right.  2125555XXX would cover the 1000 numbers I mentioned earlier.

    Thanks everyone for your help.  Much appreciated.

    Monday, October 13, 2014 1:47 PM