18
\$\begingroup\$

When making phone calls internationally, phone numbers are prefixed with a code indicating what country the number is located in. These codes are prefix codes, meaning that no code is a prefix of another.

Now, earlier today you missed a call, and you're kind of curious where that call might have come from. So you want to look up the calling code. But, being a prefix code, you're not quite sure where it ends, so you decide to write a program to separate the calling code from the rest of the number.

Input

As input, you will recieve a string consisting of the digits 0-9. The first few digits will be one of the country calling codes listed below (this means the first digit will never be 0). After the country calling code, the rest of the input will contain zero or more digits in any order - it is not guaranteed to be a valid phone number. Your program must be able to handle inputs containing at least 15 digits

Output

Your program should output the unique country calling code that is a prefix of the number. The valid outputs are as follows:

1
20
211
212
213
216
218
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
260
261
262
263
264
265
266
267
268
269
27
290
291
297
298
299
30
31
32
33
34
350
351
352
353
354
355
356
357
358
359
36
370
371
372
373
374
375
376
377
378
379
380
381
382
383
385
386
387
389
39
40
41
420
421
423
43
44
45
46
47
48
49
500
501
502
503
504
505
506
507
508
509
51
52
53
54
55
56
57
58
590
591
592
593
594
595
596
597
598
5993
5994
5997
5999
60
61
62
63
64
65
66
670
672
673
674
675
676
677
678
679
680
681
682
683
685
686
687
688
689
690
691
692
7
800
808
81
82
84
850
852
853
855
856
86
870
875
876
877
878
879
880
881
882
883
886
888
90
91
92
93
94
95
960
961
962
963
964
965
966
967
968
970
971
972
973
974
975
976
977
979
98
991
992
993
994
995
996
998

This list is based on the codes listed on Wikipedia's list of country calling codes page as of revision 915410826, with a few modifications

  • All codes listed as unassigned or discontinued and some codes listed as reserved for future use were omitted
  • If a code listed on Wikipedia is a prefix of another, the latter was omitted
  • If a single country or territory would have more than one code, and if those codes would have a common prefix, those codes are omitted in favour of their common prefix.

This may result in independent countries being lumped together, or disputed territories being lumped in with a particular claimant. This is not intended as a political statement, and decisions about the inclusion or omission of territories and states were made based on the codes, not any beliefs I hold regarding the ownership or sovereignty of the entities using them.

If given an input that does not begin with any of these codes, your program's behaviour is undefined.

And finally:

Test cases

input -> output
5292649259 -> 52
3264296721 -> 32
1550 -> 1
33121394 -> 33
7 -> 7
2542112543 -> 254
2005992972 -> 20
350 -> 350
360 -> 36
8505234469 -> 850
9795586334 -> 979
148985513598795 -> 1
222222 -> 222
5999995 -> 5999
\$\endgroup\$
  • \$\begingroup\$ Perhaps you should do input | output instead with a dash-line underneath unless you want input to be translated to output. \$\endgroup\$ – JL2210 Sep 19 at 2:35

11 Answers 11

9
\$\begingroup\$

05AB1E, 28 25 24 bytes

η•A󾫸tEΓ∞ζ∊u½d•.¥¤ØªKн

Try it online!

η                            # prefixes of the input
 •A󾫸tEΓ∞ζ∊u½d•            # compressed integer 211112166111113621489811655218129
                 .¥          # undelta: [0, 2, 3, 4, 5, 6, 8, 9, 15, 21, 22, 23, 24, 25, 26, 29, 35, 37, 38, 42, 50, 59, 67, 68, 69, 75, 80, 85, 87, 88, 96, 97, 99, 108]
                   ¤         # last element of that list: 108
                    Ø        # nth prime: 599
                     ª       # append it to the list
                      K      # remove all those values from the list of prefixes
                       н     # get the first prefix left
\$\endgroup\$
9
\$\begingroup\$

JavaScript (ES6),  75 73  71 bytes

Saved 1 byte thanks to @Shaggy
Saved 2 bytes thanks to @Neil

s=>/1|7|(2[^07]|3[578]|42|599?|50|6[789]|8[0578]|9[679]|.)./.exec(s)[0]

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I think 599?|50 can replace 599|5[09]. \$\endgroup\$ – Neil Sep 18 at 19:03
  • \$\begingroup\$ @Neil Indeed. Thanks! \$\endgroup\$ – Arnauld Sep 18 at 19:08
  • \$\begingroup\$ Does s=>/(2[^07]|3[578]|42|599?|50|6[789]|8[0578]|9[679]|[^17]|)./.exec(s)[0] work for 72 bytes? \$\endgroup\$ – ovs Sep 19 at 15:29
  • 1
    \$\begingroup\$ @ovs It does, but the current version is actually 71 bytes -- the byte count was outdated. \$\endgroup\$ – Arnauld Sep 19 at 15:46
6
\$\begingroup\$

Retina 0.8.2, 60 bytes

!`^(2[1-69]?|3[578]?|42?|599?|50?|6[789]?|8[578]?|9[679]?)?.

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Your input in the TIO already includes the answer ;) I know your code is not using them, but it looks a bit confusing tbh. \$\endgroup\$ – Kevin Cruijssen Sep 19 at 7:32
3
\$\begingroup\$

Python 3, 120 78 bytes

f=lambda n:{n//10+3}-{*b'	 &()-5>FGHSXZ[cdf',602}and f(n//10)or n

Try it online!

Contains some unprintables:

00000000: 663d 6c61 6d62 6461 206e 3a7b 6e2f 2f31  f=lambda n:{n//1
00000010: 302b 337d 2d7b 2a62 2705 0306 0708 090b  0+3}-{*b'.......
00000020: 0c18 191a 1b1c 1d20 2628 292d 353e 4647  ....... &()-5>FG
00000030: 4853 585a 5b63 6466 272c 3630 327d 616e  HSXZ[cdf',602}an
00000040: 6420 6628 6e2f 2f31 3029 6f72 206e       d f(n//10)or n

Somewhat ungolfed (earlier) version:

f=lambda n:{n/10}-{0,2,3,4,5,6,8,9,21,22,23,24,25,26,29,35,37,38,42,50,59,599,67,68,69,80,85,87,88,96,97,99}and f(n/10)or n

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Bash, 328 341 410 bytes

Not very competitive for a golfing score, but each of these helps my bash skills!

Saved 13 bytes by eliminating handling 2 byte run-length values; storing only 3 bytes adds 8 bytes to T, but makes the case statement much simpler.

Saved 69 bytes by changing approach from bash expansion to storing deltas. The previous TIO link is at the bottom of my answer.

T='16D73r423112r62r72r6F1224r53-03511322rZr32r9L1611-01Fr9BrD2112V12-025r9-029r8-0202rB2r7-0308-162121E5r832-02082r72Cr52-3UR132'
A(){
V=$[V+36#$1]
S="$S $V"
}
R(){
read -n$1 d
}
while read -n1 c;do
case $c in -)R 3;A $d;;r)R 1;for((i=1;$i<=36#$d;i++)){ A 1;};;*)A $c;;esac;done<<<$T
for s in $S;do [[ $1 =~ ^$s ]]&&echo $s;done

Try it online!

  • Sorted the list of prefixes numerically
  • T is a "sort of" run-length encoded string showing the delta from the previous value. Each character is one of the following:
    • A base36 value showing the increase from the previous value
    • 'r': indicates that the next character indicates the the base36 encoded number of repeated delta values of 1.
    • '-': indicates that the next 3 characters are the next delta value

The string T="16D73r42 [...] -3UR132" following the rules above becomes a list of deltas: "1 6 D 7 3 r4 2 [...] 4995 1 3 2"

Could save 2-3 more bytes by using a higher radix than 36 (like 62-64) but Excel only natively supports up to 36, and that's what used to do the list of deltas and their conversions.

  • On running, T is parsed and expanded into the string S used for the comparison of the phone number given in command line argument 1.

Expanding T, S becomes: "1 7 20 27 30 31 32 33 34 36 [...] 5993 5994 5997 5999"

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Perl 5 (-p), 44 bytes

$\=chop until/^599$/+vec"\x7D\x03\xE0\x27\x68\x04\x04\x08\x38\x00\xA1\x01\x0B",$_,1

Try it online!

Both TIO and SO have troubles with unprintable chars, so the program is shown with escape sequences. Here's a hexdump of the actual 44 bytes:

0000000: 245c 3d63 686f 7020 756e 7469 6c2f 5e35  $\=chop until/^5
0000010: 3939 242f 2b76 6563 227d 03e0 2768 0404  99$/+vec"}..'h..
0000020: 0838 00a1 010b 222c 245f 2c31            .8....",$_,1
\$\endgroup\$
1
\$\begingroup\$

PHP, 219 bytes

I feel like there's a lot of room for improving the regex - golfed it as far as I can go but I'll bet it can be way shorter....

preg_match('/(1|7|2(0|1[12368]|[2346].|5[^9]|7|9[01789])|3[578]?.|42?[013]|5([1-8]|0.|99?[3479])|6([0-6]|7[^1]|8[^4]|9[012])|8(0[08]|[1246]|5[02356]|7[05-9]|8[0-368])|9([0-58]|6[^9]|7[^8]|9[1-8]))/',$argn,$r);echo$r[0];

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Java 8, 84 bytes

s->s.replaceAll("(1|7|(2[^07]|3[578]|42|599?|50|6[789]|8[0578]|9[679]|.).).*","$1");

Port of @Arnauld's JavaScript regex, so make sure to upvote him!

Try it online.

Explanation:

s->                    // Method with String as both parameter and return-type
  s.replaceAll("(1|7|(2[^07]|3[578]|42|599?|50|6[789]|8[0578]|9[679]|.).).*",
                       //  Replace this regex-match
               "$1");  //  With this replacement

Regex explanation:

(1|7|(2[^07]|3[578]|42|599?|50|6[789]|8[0578]|9[679]|.).).*  // MATCH:
 1                                                           //  a 1
  |7                                                         //  or a 7
    |(                                                )      //  or:
      2[^07]                                                 //   a 2 not followed 0 nor 7
            |3[578]                                          //   or a 3 followed by 5, 7, or 8
                   |42                                       //   or a 42
                      |599?                                  //   or a 59 or a 599
                           |50                               //   or a 50
                              |6[789]                        //   or a 6 followed by 7, 8, or 9
                                     |8[0578]                //   or an 8 followed by 0, 5, 7, or 8
                                             |9[679]         //   or a 9 followed by 6, 7, or 9
                                                    |.       //   or any single digit
                                                       .     //  followed by any single digit
(                                                       )    //  All captured in capture group 1
                                                         .*  //  With 0 or more digits following

$1                                                           // REPLACEMENT:
$1                                                           //  The match of capture group 1,
                                                             //  (effectively removing the
                                                             //   remaining digits of `.*`)
\$\endgroup\$
0
\$\begingroup\$

Python 3, 96 bytes

lambda s:re.sub('(1|7|(2[^07]|3[578]|42|599?|50|6[789]|8[0578]|9[679]|.).).*',r'\1',s)
import re

Try it online!

Port of Arnauld's JavaScript answer.

\$\endgroup\$
0
\$\begingroup\$

Scala, 411 402 330 bytes

This is assuming that the argument only contains digits.

"(1|(2(0|(1[12368])|([2346]\\d)|(5[^9])|7|(9[^2-6])))|(3(([0-4])|([57]\\d)|6|(8[^48])|9))|(4([^2]|(2[013])))|(5((0\\d)|[^09]|(9([^9]|(9[3479])))))|(6([0-6]|(7[^1])|(8[^4])|(9[0-2])))|7|(8((0[08])|[1246]|(5[02356])|(7[05-9])|(8[^4579])))|(9([0-58]|(6[^9])|(7[^8])|(9[^079]))))(.*)".r.unapplySeq(args(0)).foreach(l=>println(l.head))

Try it online!

\$\endgroup\$
-4
\$\begingroup\$

Python 3, 312 Bytes

I'm not very proficient with reg expressions, so I used this very inefficient trick instead. This is my first answer, and I'm not too familiar with the rules, so I hope webscraping is not against them.

import requests as r;from bs4 import BeautifulSoup as B
n=['1']+str(B(r.get("https://codegolf.stackexchange.com/questions/193101/where-are- 
they-calling-from.html").content,'html.parser').find_all('code')[2]).split()[1:-1]
x=input();print(x[:4]if x[:4]in n else x[:3]if x[:3]in n else x[:2]if x[:2]in n else x[0])
\$\endgroup\$
  • 7
  • \$\begingroup\$ Hello and welcome on this site! May I suggest you as a first tip: instead of getting things you want to check against from the internet, put it into the code as an array or sth. similar. Another tip: you can work on TIO. There you can code and compile your code and then share it to this platform that others can verify what you have done. Also you can see how many bytes you already wrote. The main function that counts here can be put into the code section on TIO. Function calls, header stuff and test cases etc. can be put into header and footer sections. \$\endgroup\$ – pixma140 Sep 19 at 9:07
  • \$\begingroup\$ Thank you for the tips. I'll implenent your suggestions. \$\endgroup\$ – Michele Bastione Sep 19 at 9:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.