ruby - Codewars:“返回或旋转”:为什么我尝试的解决方案不起作用?
问题描述
这些是 Codewars ( https://www.codewars.com/kata/56b5afb4ed1f6d5fb0000991/train/ruby ) 上给出的说明:
输入是字符串字符串。将字符串切成大小为 sz 的块(这里的块是初始字符串的子字符串)(如果最后一个块的大小小于 sz,则忽略它)。
如果一个块表示一个整数,例如其数字的立方和可以被 2 整除,则反转该块;否则将其向左旋转一个位置。将这些修改后的块放在一起并将结果作为字符串返回。
如果
sz <= 0 或者如果 str 为空,则返回 ""
sz 大于 (>) str 的长度,因此不可能获取大小为 sz 的块,因此返回 ""。
Examples:
revrot("123456987654", 6) --> "234561876549"
revrot("123456987653", 6) --> "234561356789"
revrot("66443875", 4) --> "44668753"
revrot("66443875", 8) --> "64438756"
revrot("664438769", 8) --> "67834466"
revrot("123456779", 8) --> "23456771"
revrot("", 8) --> ""
revrot("123456779", 0) --> ""
revrot("563000655734469485", 4) --> "0365065073456944"
这是我的代码(在 Ruby 中):
def revrot(str, sz)
# your code
if sz > str.length || str.empty? || sz <= 0
""
else
arr = []
while str.length >= sz
arr << str.slice!(0,sz)
end
arr.map! do |chunk|
if chunk.to_i.digits.reduce(0) {|s, n| s + n**3} % 2 == 0
chunk.reverse
else
chunk.chars.rotate.join
end
end
arr.join
end
end
它通过了 13/14 测试,我得到的错误如下:
STDERR/runner/frameworks/ruby/cw-2.rb:38:in `expect': Expected: "", instead got: "095131824330999134303813797692546166281332005837243199648332767146500044" (Test::Error)
from /runner/frameworks/ruby/cw-2.rb:115:in `assert_equals'
from main.rb:26:in `testing'
from main.rb:84:in `random_tests'
from main.rb:89:in `<main>'
我不确定我做错了什么,我一直试图找出它可能是一个多小时。你可以帮帮我吗?
解决方案
我会让其他人识别您代码的问题。我只是想展示如何加快解决方案。(我不会包含处理边缘情况的代码,例如字符串为空。)
您可以利用两个观察结果:
- 当且仅当整数是奇数时,整数的立方是奇数;和
- 当且仅当奇数的个数是奇数时,整数集合的总和是奇数。
因此我们可以写
def sum_of_cube_odd?(str)
str.each_char.count { |c| c.to_i.odd? }.odd?
end
考虑上一个示例中的 4 位数字组"563000655734469485"
。
sum_of_cube_odd? "5630" #=> false (so reverse -> "0365")
sum_of_cube_odd? "0065" #=> true (so rotate -> "0650")
sum_of_cube_odd? "5734" #=> true (so rotate -> "7345")
sum_of_cube_odd? "4694" #=> true (so rotate -> "6944")
所以我们要返回"0365065073456944"
。
让我们创建另一个助手。
def rotate_chars_left(str)
str[1..-1] << s[0]
end
rotate_chars_left "0065" #=> "0650"
rotate_chars_left "5734" #=> "7345"
rotate_chars_left "4694" #=> "6944"
我们现在可以编写 main 方法了。
def revrot(str, sz)
str.gsub(/.{,#{sz}}/) do |s|
if s.size < sz
''
elsif sum_of_cube_odd?(s)
rotate_chars_left(s)
else
s.reverse
end
end
end
revrot("123456987654", 6) #=> "234561876549"
revrot("123456987653", 6) #=> "234561356789"
revrot("66443875", 4) #=> "44668753"
revrot("66443875", 8) #=> "64438756"
revrot("664438769", 8) #=> "67834466"
revrot("123456779", 8) #=> "23456771"
revrot("563000655734469485", 4) #=> "0365065073456944"
写起来可能会快一些
require 'set'
ODD_DIGITS = ['1', '3', '5', '7', '9'].to_set
#=> #<Set: {"1", "3", "5", "7", "9"}>
def sum_of_cube_odd?(str)
str.each_char.count { |c| ODD_DIGITS.include?(c) }.odd?
end
推荐阅读
- gremlin - Gremlin 查找具有给定值的“任何”属性的所有顶点
- python - 加快学校项目数据文件读取程序
- javascript - 如何在 jQuery 和 html 中计算文本框的值
- sql-server - XPath/XQuery - 将具有命名空间属性的字段作为值/查询获取?
- java - Android Studio 初学者;
- python - 熊猫如何用 int64 空标记 -999999 替换
没有铸造浮动? - python - 将 mongodb 集合名称作为变量不起作用
- php - 如何防止在 Symfony 中延迟加载易受攻击的实体
- sql - 如何限制oracle表的记录有限
- google-app-engine - 部署 gcloud 应用引擎时的权限