Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@danielpclark
Last active November 10, 2015 05:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielpclark/b8c7baa44831a5e398c6 to your computer and use it in GitHub Desktop.
Save danielpclark/b8c7baa44831a5e398c6 to your computer and use it in GitHub Desktop.
Attempting to solve a kata and not having any luck
# http://www.codewars.com/kata/55983863da40caa2c900004e/train/ruby
# Only a few of the varied attempts are recorded...
# First recorded attempt
def next_bigger(n)
case n.to_s.chars.map(&:to_i).combination(2)
when ->x{x.all?{|a,b|a>=b}} # Edge case #1
return -1
when ->x{x.all?{|a,b|a<b}} # Edge case #2
return n.to_s.gsub(/(.*)(.)(.)\z/, '\1\3\2').to_i
end
b = BaseCustom.new(n.to_s.chars.sort_by{|i|i.to_i})
# Edge case #3
if n.to_s[0] == b.base(0)
return "#{b.base(1)}#{n.to_s.sub(b.base(1),b.base(0))[1..-1]}".to_i
end
char_count = ->x{
x.to_s.
chars.
inject({}){|acc,a|
acc.merge(a.to_i => acc[a.to_i].to_i+1)
}
}
increment = ->x{
x = b.base b.base(x.to_s) + 1
return x if (char_count.(x).values == char_count.(n).values)
x = increment.(x)
}
increment.(n).to_i
end
# This is my own code available at
# http://github.com/danielpclark/BaseCustom
class BaseCustom
def initialize(array_in, delim = "")
if array_in.is_a?(String)
array_in = array_in.split(/#{delim}/)
end
if not array_in.is_a?(Array)
raise "Invalid type! Please provide a String or an Array."
end
array_in = array_in.flatten
if array_in.any? { |i| not i.is_a?(String) }
raise "Invalid type! Each array element must be a String."
end
if !delim.is_a? String
raise "Invalid delimiter type! Delimiter value must be a String."
end
if array_in.any? { |i| i.length > 1 }
if delim.empty?
raise "Error! You must define a delimiter when using multiple characters for a base."
end
end
@BASE_PRIMITIVES_ARRAY = array_in.uniq
@BASE_PRIMITIVES_HASH = Hash[@BASE_PRIMITIVES_ARRAY.each_with_index.map {|x,idx| [x, idx]}]
@delim = delim
end # initialize
def base(input_val)
if input_val.is_a?(String)
if input_val.split(/#{@delim}/).any? { |i| not @BASE_PRIMITIVES_ARRAY.include?(i) }
raise "Characters used are not in predefined base!"
end
i, i_out = 0, 0
input_val.split(/#{@delim}/).reverse.each do |c|
place = @BASE_PRIMITIVES_HASH.size ** i
i_out += @BASE_PRIMITIVES_HASH[c] * place
i += 1
end
i_out
# end input_val.is_a?(String)
elsif input_val.is_a?(Integer)
return @BASE_PRIMITIVES_HASH.first[0] if input_val == 0
number = input_val
result = ""
while(number != 0)
result = @BASE_PRIMITIVES_ARRAY[number % @BASE_PRIMITIVES_ARRAY.size ].to_s + @delim + result
number = Integer(number/@BASE_PRIMITIVES_ARRAY.size)
end
result
# end input_val.is_a?(Integer)
else
raise "#{input_val.class} is not a supported type!"
end
end # base
def length
return @BASE_PRIMITIVES_ARRAY.length
end
def all
return @BASE_PRIMITIVES_ARRAY.join(@delim)
end
end
# Second recorded attempt
def next_bigger(n)
m = n.to_s.chars.permutation
return -1 if m.peek.combination(2).all?{|a,b|a.to_i>=b.to_i}
loop do
v = m.next.join.to_i
return v if v != n && v > n
end
end
# Third recorded attempt
def next_bigger(n)
return -1 if n.to_s.chars.combination(2).all?{|a,b|a.to_i>=b.to_i}
last = 0
n.to_s.reverse.chars.each.with_index {|c,i|
if c == n.to_s[0] && i.+(1)==n.to_s.length
return "#{last.to_s}#{c}#{n.to_s[2..-1].chars.sort_by{|i|i.to_i}.join}".to_i
elsif c.to_i < last
return "#{n.to_s[0..-(i+2)]}#{n.to_s.slice(-1,i+1)}#{c}".to_i
end
last = c.to_i
}
end
# Fourth recorded attempt
def next_bigger(n)
m = n.to_s.chars.permutation
return -1 if m.peek.combination(2).all?{|a,b|a.to_i>=b.to_i}
marker = Enumerator.new do |y|
(1..Float::INFINITY).each.with_index {|a,i|
a.times{|b|
y << [i,b+1]
}
}
end
marker.each do |many, pos|
ar = []
many.times { ar << m.next.join.to_i }
v = ar.sort.each do |x|
return x if x != n && x > n
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment