电话号码乱码


19

您知道如何收到语音邮件,并且此人的联系不好,并且您正在尝试找出如何回叫他们,但是您不确定他们是“ 5”还是“ 8”说过?

这就是挑战。

好消息是,呼叫者两次读出了他们的电话号码,但两个地方都出现了乱码。

您的程序应采用这样的输入:

5551231234 / 5551231234

前十位数是语音邮件中第一次说出电话号码的地方,而第二组是第二次语音电话中说出来的号码。只有...看起来会更像这样:

555?ABC1_36? / 55?522_1?234
  • 一个数字后跟一个问号意味着该数字是最好的猜测(例如,“ 5?”表示“可能是5,与重复比较”)。
  • 下划线表示一个已知的丢失数字,该数字由于静电而变得模糊不清,根本无法解密。
  • 字母就是:字母。将它们视为各自的数字
    • ABC-> 2,DEF-> 3,GHI-> 4,JKL-> 5,MNO-> 6,PQRS-> 7,TUV-> 8,WXYZ-> 9
    • 所有示例输入均使用大写字母(您可以安全地忽略ToUpper()调用)
    • 如果您的语言在小写形式下效果更好,则可以自由使用小写形式输入,并忽略ToLower()调用。只需在您的答案中注明即可。

您还可以假设以下判断调用:

5? / _     -> 5  //5 is the best guess we have, use it
5? / 5?    -> 5  //uncertain, but matching
5? / 4?    -> ?  //conflict
 5 / 4     -> ?  //conflict
5? / 4     -> 4  //solid information overrides possible value
 5 / 4?    -> 5  //solid information overrides possible value
 _ / _     -> ?  //no information available

另外,您可以假定所有输入将包含十位数的电话号码,不包括问号。非十位数的输入(例如1234567 / 1234567)可以被视为不可解决的(错误的输出)或引发错误。

输入项

0-9A-Z _?/如上所述,一行字符。

输出量

如果可以将其解析为一个有效的十位数电话号码,请输出该电话号码。否则,输出某种形式的错误指示(例如-1,false或空行)。

与往常一样,最短的胜利。

输入样例:

1234567890 / 1234567890
1234567890? / 1234567890
123456789_ / 1234567890
1234567890? / 123456789_
1234567890 / 1234567890?
1234567890 / 123456789_
123456789_ / 1234567890?
1234567890? / 1234567890?
1234567890? / 1234567891?
123456789_ / 123456789_
555CALLUS1 / 5552255871
404_12?6039 / 4041?1560_9
_GETREVENGE / 16?36?_2838_
1?691460_50 / 16_14609?50
61?08977211 / 612?897725?1
40?0INSTA__ / 8?00_NSTI?LL
3985_534?10 / 39?8?5053_10
7__7294?737 / 7797299?_37
28?897_384?1 / _8?89763861
271168090_ / 27116800?09
6802?148343 / 67?01148343
94_11628?2?6? / 9491162_47?
17?4285_689 / 1__26?52689
6_311?95_38 / 6731194?7?38
380?7DRAGON / 3807378?5?66
4?647_93236 / 5646?6?9__36
365?268898_ / 366267?7?984
GRATEDBATE / IRATEDBATE
5307_079?93 / ____8_____
535_3_0255 / 52?5_3_024?5
55_____088 / 54?2397207?7?
6_48398_95 / _946?398?6_5?
_0_312_3_1 / 81?53123?1?71
____1_____ / 64?255?508?61
8427820607 / 6?424?8?__6?07
50_3707__6 / 52?8375?74?56
615___8255 / 62?526?983?2?1?
__652618__ / 8365261__0
149___933_ / 1_9677?92?31
___7?281562 / 3438?28154?2
5?7?7?___8?3?7?4 / 57_855837_
605_272481 / 605427__81
86?569__731 / 88560?0?7721
1__91654?15 / 17?9?9165715
800NWABODE / 80069ABI?DE
8___9017_0 / 8_2494?12?9_
_024?5?91?470 / 304?17908?7_
42510704_2 / 4_51070492
9338737_89 / 93_873PLUS
327762_401 / 327_MASH01
33093_2058 / 3309_12058
4061_33578 / 40619_3578
559_383197 / 559938_197
94_9746084 / 9459746_84
1_37655238 / 163POLKA_T
_672FRIZZY / 767237499_
8_76318872 / TIP63188_2
51_8404321 / 5178404_21
358_030314 / 358603_314
2597_85802 / 25979_5802
77141_1408 / 7714_91408
330858_457 / 330_586457
4686079_39 / 46_6079239
86457508_6 / 8_45750826
523226626_ / _23BANNANA
_ISSY_ISSY / 44__9548?79?
6?00B_YJILT / 800289KILL?
2?52803___0 / 1526?0390?61?
FI?ND___T?HE / EAS?T?EREGGS?
0_231?95_38 / 0723194?7?38
0?647_39236 / 0646?6?3__36
025?267798_ / 06?6265?9?984
0061_33578 / _0619_3578

我只是确保所有可能的边缘情况都被覆盖了(前11个条目),但除此之外,它几乎是随机的。

更新资料

底部的四个条目添加了前导零(根据Jonathan Allan的建议)。

样本输入的正确输出:

https://pastebin.com/gbCnRdLV

基于乔纳森·艾伦Jonathan Allan)条目的输出(格式化输出是理想的)。


我们是否必须将输入作为单个字符串,用分隔" / ",还是可以将它们作为两个标准输入?
L3viathan '17

@ L3viathan我最初的想法是必须使用一个字符串。
Draco18s

7
@ Draco18的单弦并没有带来任何挑战
fəˈnɛtɪk 17-4-22

1
@ fəˈnɛtɪk没有人在沙箱中说过什么,但是我使用输入对没有什么反对。这只是我最初的构想。
Draco18s

1
谁用字母作为电话号码留下语音邮件?
乔纳森·艾伦

Answers:


3

果冻,84 字节

+4个字节-我认为在所有情况下它的行为都应该相同,因此我已使用来将键盘查找整数转换回数字字符+49Ọ

”?e‘ḣ@µ”_eḤ‘ẋ@
;Ṃµ68DṬ+3RØAṁẇ@€FT+49Ọȯµ€Fṡ2i”?Ḃ$ÐḟÇ€
ḟ⁶ṣ”/Ç€ZLÐṂ€Q€LỊ$ÐfF€Ḣ€ḟ”_µL⁼⁵ȧ

该函数采用指定格式的字符串,并以字符列表形式返回电话号码;如果无效,则返回零。作为程序,它就像字符串一样被打印。

他们的工作方式可以重复多次
(例如"123456789_ / 123456789_ / 1234567890"
,甚至只说一次,定义的逻辑将适用。

在线尝试!,或查看所有示例输入

怎么样?

”?e‘ḣ@µ”_eḤ‘ẋ@ - Link 1, helper to vary the length of a 2-slice: list s
”?             - literal '?'
  e            - exists in s                   (1 or 0)
   ‘           - increment                     (2 or 1)
    ḣ@         - head with reversed @rguments  (s or s[:1] - removes 2nd value if not '?')
      µ        - monadic chain separation, call that t
       ”_      - literal '_'
         e     - exists in t                   (1 or 0)
          Ḥ    - double                        (2 or 0)
           ‘   - increment                     (3 or 1)
            ẋ@ - repeat t that many times      (t*3 or t - [`_`]->['_','_','_'])

;Ṃµ68DṬ+3RØAṁẇ@€FT+49Ọȯµ€Fṡ2i”?Ḃ$ÐḟÇ€ - Link 2, reformat a phone number: char list of [0-9][A-Z], p
;                                     - concatenate p with
 Ṃ                                    - minimum of p - (?<_<0<1<...<9<A<...<Z - never "?" however, since it only follows a digit.)
                                      -   - this is simply to make a 2-slice with the last character on the left, as used at the very end of this link.
  µ                                   - monadic chain separation call that q
                       µ€             - monadic chain separation, for €ach v in q do:
   68                                 -   literal 68
     D                                -   cast to a decimal list -  [6,8]
      Ṭ                               -   untruth                -  [0,0,0,0,0,1,0,1]
       +3                             -   add 3                  -  [3,3,3,3,3,4,3,4]
         R                            -   range                  -  [[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3,4],[1,2,3],[1,2,34]]
          ØA                          -   uppercase alphabet     -  ABCDEFGHIJKLMNOPQRSTUVWXYZ
            ṁ                         -   mould like the range ^ -  [ABC,DEF,GHI,JKL,MNO,PQRS,TUV,WXYZ]
             ẇ@€                      -   sublist v exists in that? for €ach, with reversed @rguments
                F                     -   flatten        (e.g. 'E' -> [0,1,0,0,0,0,0,0]; '4' -> [0,0,0,0,0,0,0,0]
                 T                    -   truthy indexes (e.g. 'E' -> [2]; '4' -> [])
                  +49                 - add 49
                     Ọ                - cast to character
                      ȯ               -   or             (e.g. 'E' -> [3]; '4' -> '4')
                         F           - flatten
                          ṡ2          - all slices of length 2
                                 Ðḟ   - filter discard if:
                                $     -   last two links as a monad:
                            i         -     first index of
                             ”?       -     literal '?'   (first index returns 0 if none exists)
                               Ḃ      -   mod 2 (so this filter discards pairs starting with '?')
                                   Ç€ - call the last link (1) as a monad for €ach slice

ḟ⁶ṣ”/Ç€ZLÐṂ€Q€LỊ$ÐfF€Ḣ€ḟ”_µL⁼⁵ȧ - Main link: string (or char list) s
ḟ                               - filter discard any:
 ⁶                              - literal ' '
  ṣ                             - split on:
   ”/                           - literal '/'
     Ç€                         - call the last link (2) as a monad for €ach
       Z                        - transpose
         ÐṂ€                    - filter, for €ach, keep items with minimal:
        L                       -   length
            Q€                  - de-duplicate €ach
                 Ðf             - filter keep items with:
                $               - last two links as a monad:
              L                 -   length
               Ị                -   insignificant? (=1 effectively here)
                   F€           - flatten €ach
                     Ḣ€         - head €ach
                       ḟ        - filter discard any of:
                        ”_      -   literal '_'
                          µ     - monadic chain separation, call that r
                           L    - length(r)
                             ⁵  - literal 10
                            ⁼   - equal?
                              ȧ - and r (0 if r did not result in a 10-digit list, else r)

看起来可能有错误,55_____088 / 54?2397207?7?应该解决5523972088:所有缺少的数字都存在,并且右侧的不确定数字在左侧。所有简单的情况都会运行。
Draco18s

啊,我删除了我认为是多余的过滤器,但不是。正在修复...
Jonathan Allan

以前去过那里-那不是高尔夫!;)
Draco18s

糟糕的是,我花了一段时间(在测试时发现了一个不同的错误),尽管如此,它又恢复了原来的字节数,只是添加了过滤器。
乔纳森·艾伦

@ Draco18s-一切看起来对你都好吗?给出问题中测试用例的预期输出可能会很好,或者只是将无效的用例分开。
乔纳森·艾伦

7

Python 2中314个 307 274字节

lambda s:g(*''.join(q<n<"["and`(int(n,36)-4-(n>"R")-(n>"Y"))//3`or n for n in s).split(" / "))
def g(a,b,s=str.startswith):
 if b:c,d,e,f=a[0],a[1:],b[0],b[1:];b=(c==e and[c,q][c=="_"]or"_"in c+e and min(c,e)or[q,c,e][s(f,q)-s(d,q)])+g(d[s(d,q):],f[s(f,q):])
 return b
q="?"

在线尝试!


5

Python 3中,549 530 509 453 449 410个 406 394 393 391字节

我相信这可以改善,但这是一个开始:

def f(e,z,q="?",u=str.isnumeric):
 if e+z in(e,z):return""
 o,O,t,T,*x=e[0],e[1:2],z[0],z[1:2],e[1:],z[1:]
 if"?"in o+t:return f([e,x[0]][o==q],z)
 if u(o):
  if u(t):return t+f(*x)if O==q!=T else o+f(*x)if o==t or T==q!=O else 1
  return o+f(*x)
 if u(t):return t+f(*x)
def g(s):
 for a,b in zip(map(chr,range(65,91)),"2223334445556667777888999"):s=s.replace(a,b)
 return f(*s.split(" / "))

我使用str.translate的是字母和包装函数,g以使用所需的格式进行输入。实际函数f是递归的,并且对于不明确的输入将失败。虽然我仍然有很多问题,所以我敢肯定还有很多改进的余地。

改进之处:

  • 通过组合条件节省了19个字节
  • 用三进制保存21个字节
  • @TuukkaX,使用字典理解而不是手动字典节省了56个字节
  • 通过切换到@ovs建议的方法,通过@TuukkaX的改进节省了4个字节
  • 通过@ovs的改进节省了38个字节(并删除了最后一个可移动空格)
  • 通过str.isnumeric在关键字参数中定义来节省4个字节
  • 使用组合比较运算符(例如T==q!=O)节省了12个字节
  • not(e or z)变成节省了1个字节e+z in(e,z)
  • 通过保存常用字节节省2个字节 (E,Z)

它包含不包含最上一行默认值的字典理解。我讨厌3的序列,但是这些序列可能会被数学代替。
Yytsi '17


@ovs尼斯。字母表可以更改为map(chr,range(65,91))
Yytsi '17

2
RE:将其作为放弃声誉的社区Wiki,共识是“不”,只接受友好的帮助,并像您一样相信它。
乔纳森·艾伦

1
我每次回到这里都发誓,这个答案会变得更短:D
Draco18s

3

的JavaScript(ES6),180个 190 188字节

编辑:+10 +9个字节,以符合虚假的输出规则


以currying语法接受两个输入字符串(a)(b)。返回一个false或代表猜测电话号码的字符串。

a=>b=>!(s=(F=a=>a.match(/(.\??)|_/g).map(([x,y])=>(x<=9?++x:parseInt(x,36)*.32-(x>'Y'))|(x!='_'&!y)*16))(a).map((x,i)=>(x=(d=x^(y=F(b)[i]),x>y)?x:y)&&(d&16|!(d%x))?--x&15:a).join``)[10]&&s

怎么运行的

步骤#1-解析输入字符串

我们首先F()通过应用以下规则定义将字符串转换为整数数组的函数:

  • 下划线将转换为0
  • 一个数字 N或等效字母转换为(N + 1)或16(例如,“ 2”→19,“ R”→24)
  • 一个数字N或等效字母后跟问号会转换为N + 1(例如“ 2?”→3,“ R?”→8)

可以用另一种方式解释如下:

  • 0未知
  • [ 1 .. 10 ]不可靠
  • [ 17 .. 26 ]可靠

我们应用F()到两个ab。这给我们电话号码中每个数字的一对整数(x,y),对应于两种可能的解释。

步骤#2-猜测数字

对于每对(x,y),我们计算:

  • d = x异或
  • x =最大(x,y)可靠的值总是比不可靠的值更可取

如果 x == 0,则表示两个输入均为下划线字符。因此,在这种情况下,数字是未知的。

如果x!= 0,则在满足以下条件之一的情况下,我们可以安全地推断数字:

condition       | interpretation
----------------+------------------------------------------------------
(d AND 16) != 0 | one input is unreliable and the other one is reliable
d == 0          | both inputs are identical
d == x          | one input is an underscore

最后两个条件可以与合并!(d % x)。因此,最终公式为:

x && (d & 16 || !(d % x))

如果为true,则通过计算将x转换回猜测的数字(x-1)AND 15

测试用例

(由于控制台代码片段不支持更多的输出历史记录,因此仅前50个。)


1234567890? / 1234567890?应该下定决心1234567890。现在,您的代码输出123456789?比输入的信息还少。Assume: 5? / 5? -> 5 //uncertain, but matching
Draco18s

@ Draco18s与我所说的相反,我包括了51个测试用例。因此,第一个掉落了,一切都移动了一行。(现在已解决。很抱歉。)
Arnauld

啊啊 尽管如此,它应该为那些测试用例输出某种假或错误值。但否则看起来不错。
Draco18s

2

Perl 5、211字节

...没有缩进和\ n换行符

@i=map{y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/22233344455566677778889999/;$_}split' / ',shift;
print map{
  $_=join'',map{s,(\d\??|_),,;$1}@i;
  /((\d)\??\2\??|(\d)\??_|_(\d)\??|(\d)\d\?|\d\?(\d))$/;$2//$3//$4//$5//$6//'?'
}1..10

在线尝试!


看起来它返回的是“最好的”(83652618?0),而不是某种假的或错误的值。
Draco18s

如果我没记错的话,这就是难题所要的。在“您还可以承担以下判断电话”标题下查看案例。或不?
Kjetil S.

抱歉,从未收到您的回复通知(没有提及)。我为判断调用所做的部分使用a ?表示没有办法解决丢失的信息,然后应将该信息落入“输出”部分:...Otherwise output some form of error indication (e.g. -1, false, or an empty line).
Draco18s

2

视网膜,150个 140 136字节

多亏了Kritixi Lithos,节省了几个字节

T`?L`#22233344455566677778889
./.

(?<=(\d)(\w#?){9}).#|.#(?=(\w#?){9}(\d)(?!#))
$1$4
#

_(?=.{9}(.))|(?<=(.).{9})_
$1$2
^(\d*)\1$|.*
$1

在线尝试!

说明:

第一行将?输入中的#所有内容转换为所有字母,并将所有字母转换为它们的数字等效项。然后,我们/从输入中删除空格和。接下来的两行处理“猜测与确定性”的情况(例如,5? \ 4将替换为4 \ 4)。删除所有#s后,第8和9行处理“数字与_”情况(_ \ 3变为3 \ 3)。然后,如果字符串的两半都匹配,则保留前10位数字。否则,电话号码无效,因此我们将删除所有内容。

适用于任意长度(和大小相等)的电话号码的备用160字节解决方案:TIO


您可以更改(/|_),以[/_]节省1个字节。另外,我认为您可以使用;代替它,x以便[^x]可以成为\w
Kritixi Lithos 17-4-23

1

PHP,251236字节

for(;a&$c=preg_replace(["#[^_?](?!\?)#","#_#"],["$0k","?<"],join("-",$argv))[++$i];)${$k+="-"==$c}.=$c<_&$c>=A?0|(ord($c)-($c>W)-($c>P)-59)/3:$c;for(;$c=${1}[$k+1];)echo($n=${1}[$k])==($m=${2}[$k++])|($b=${2}[$k++])!=$c?$c>$b?$n:$m:"?";

从命令行获取输入;运行-nr在线尝试

分解

# A: transform input
                                    # 2. replace single chars with two-character chunk and make sortable:
                                    #   replace "_" with "?<", append "k" to everything else not followed by "?"
for(;a&$c=preg_replace(["#[^_?](?!\?)#","#_#"],["$0k","?<"],join("-",$argv))[++$i];)    # (unknown "<" < unsure "?" < certain "k")
${$k+="-"==$c}.=                # if "-", next argument
        $c<_&$c>=A              # if letter
            ?0|(ord($c)-($c>W)-($c>P)-59)/3 # then translate to digit
            :$c                             # else don´t
    ;
# B: evaluate
for(;$c=${1}[$k+1];)            # loop through arguments: $c=command 2
    echo
        ($n=${1}[$k])                   # $n=digit 2
        ==                          # if digits are equal
        ($m=${2}[$k++])                 # $m=digit 3
        |
        ($b=${2}[$k++])             # $b=command 3
        !=$c                        # or "commands" are not
            ?$c>$b?$n:$m            # then get the one with the more definitive "command"
            :"?"                    # else conflict/unknown
    ;

打高尔夫球

  • preg_replace 第一:-8个字节
  • join:-2
  • $$k代替$t[$k]:-5

1

PHP,200 + 8字节

Arnaulds解决方案启发。

for($s=join($argv);$c=ord($s[$i++]);$i+=$x)$t[]=$c>90?63:15&($c<65?$c:($c-($c>80)-($c>87)-59)/3)|16*$x="?"==$s[$i];for(;$p++<10;)echo chr(($e=$t[$p]^$d=$t[$p+10])&48|!(15&$e)?min($t[$p],$d)&15|48:63);

从命令行参数获取输入;运行-nr在线尝试

修改以符合错误输出限制:(打印X不完整的数字):

  • 去掉 |48(-3个字节)
  • 替换echo chr(...);$r.=...;echo$r>1e10?X:$r;(+11字节)

分解

for($s=join($argv);$c=ord($s[$i++]);    # loop through characters of arguments
    $i+=$x)                             # skip "?"
$t[]=
    $c>90                               # if "_"
        ?63                             # then 32+16+15
        :                               # else
            15&(                            # lower 4 bits of
            $c<65                               # if digit
            ?$c                                 # then digit
            :($c-($c>80)-($c>87)-59)/3          # else letter mapped to digit
        )
        |16*$x="?"==$s[$i]                  # if next char is "?", add 16
;
for(;$p++<10;)echo chr( # loop through translated arguments
    (
        $e=$t[$p]^      # 2. $e=difference
        $d=$t[$p+10]    # 1. $d=char from 2nd argument
    )&48                # if certainties differ
    |!(15&$e)           #    or digits do not
    ?min($t[$p],$d)&15|48   # then pick the more definite digit (15|48 -> "?")
    :63             # else "?"
);

打高尔夫球

  • 解决 preg_replace_callback(-10字节)
  • 依靠10位数输入(-9)
  • 和其他打高尔夫球(-8)
  • 已移除 join定界符(-7)
  • $x作业移到末尾(-2)

1

Perl -pl 5,173个字节

sub t{$_=pop;y/A-Z/22233344455566677778889999/;/_|\d\??/g}@e=m|\S+|g;@a=t$e[0];$_=join"",map{$_.=shift@a;s/^(.+)\1$/$1/||s/_//||s/..../_/||s/.\?//;$_}t$e[2];s/\?//;$_ x=!/_/

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.