与えられた数字のケタ数
Posted feedbacks - Flatten
Nested Hidden
0が入力されたときは、
ケタ数1、最大桁の位1で良かったでしょうか。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include <stdio.h>
#include <math.h>
int main()
{
unsigned long input_data;
int digit;
printf("正の整数を入力してください : ");
scanf("%ld", &input_data);
/* 0と入力されたとき対策 */
if (input_data != 0) {
digit = 0;
}
else {
digit = 1;
}
while (input_data > 0) {
input_data /= 10;
digit++;
}
printf("ケタ数 : %d\n", digit);
printf("最大桁の位 : %d\n", (int)pow(10, digit-1));
return 0;
}
|
bashで王道?に。
1 2 3 | #!/bin/bash
n="$1"
echo "$nは${#n}桁で最大桁は$((10**(${#n}-1)))の位です。"
|
負の値の場合、"-"は桁数に入らないですよね? 最大桁に同じものがあったときは、1の位に近いものを出しています。 > digit_max(600) digits = 3 max digit = 100 > digit_max(-600) digits = 3 max digit = 100 > digit_max(0) digits = 1 max digit = 1
1 2 3 4 5 | digit_max <- function(x){
if(x < 0) x <- x * -1
cat("digits =", ifelse(x==0, 1, floor(log(x, 10))+1), "\n")
cat("max digit =", 10 ** (which.max(rev(as.integer(unlist(strsplit(as.character(x), ""))))) - 1), "\n")
}
|
ワンライナーで. 実行例: > perl -e '$l = length($ARGV[0]); print $l, "\n", 10 ** ($l-1), "\n"' 1 1 1 > perl -e '$l = length($ARGV[0]); print $l, "\n", 10 ** ($l-1), "\n"' 600 3 100 > perl -e '$l = length($ARGV[0]); print $l, "\n", 10 ** ($l-1), "\n"' 2469 4 1000
1 | perl -e '$l = length($ARGV[0]); print $l, "\n", 10 ** ($l-1), "\n"' 1
|
(figure 2469) => 4 => 1000 (figure 600) => 3 => 100 (figure 1) => 1 => 1
1 2 3 4 5 6 | (defun figure (n)
(and (plusp n)
(let ((fig (ceiling (log n 10))))
(if (zerop fig)
(values 1 1)
(values fig (expt 10 (1- fig)))))))
|
・・・あ、最大桁って最大の数字を含む桁じゃないんですね。すみません。 数学風にlogを使う方法と、スクリプト言語風に文字数をカウントする方法を使ってます。 > digit_max(-12345) digits = 5 max digit = 10000
1 2 3 4 5 | digit_max <- function(x){
if(x < 0) x <- x * -1
cat("digits =", ifelse(x==0, 1, floor(log(x, 10))+1), "\n")
cat("max digit =", 10 ** (nchar(as.character(x))-1), "\n")
}
|
いかんいかん。端折り過ぎたorz (figure 2469) => 4 => 1000 (figure 600) => 3 => 100 (figure 1) => 1 => 1 (figure 0) => 1 => 1 (figure -2469) => 4 => 1000
1 2 3 4 5 6 | (defun figure (n)
(cond ((zerop n) (values 1 1))
(t (let ((fig (ceiling (log (abs n) 10))))
(if (zerop fig)
(values 1 1)
(values fig (expt 10 (1- fig))))))))
|
何も考えずに超簡単に。 (4, 1000) (3, 100) (8, 10000000) (6, 100000) (7, 1000000) (1, 1)
1 2 3 4 5 6 7 8 9 10 11 12 13 | def getKetaAndKurai(num):
s = str(num)
keta = len(s)
kurai = int("1" + "0" * (keta - 1))
return (keta, kurai)
print getKetaAndKurai(2469)
print getKetaAndKurai(600)
print getKetaAndKurai(12378990)
print getKetaAndKurai(414879)
print getKetaAndKurai(3141592)
print getKetaAndKurai(1)
|
1 2 3 4 | function figure(x){
y = size(string(int(x)))
[y, pow(10,y-1)]
}
|
ぜんぜん考えてません。0のときこうなりました。 (digits 0) =>0 =>1/10
1 2 3 4 5 6 | (define (digits n)
(define (f n)
(if (zero? n) 0
(+ 1 (f (quotient n 10)))))
(let1 digit (f n)
(values digit (expt 10 (- digit 1)))))
|
文字上の桁数を数えています。 Prologの人気のなさに絶望した。 ところで、0は一桁、でいいんでしょうかね。
1 2 3 4 5 6 7 8 9 10 11 | val(X,_,X).
figure(N,(K,X)):-
atom_chars(N,N1),
length(N1,K),
maplist(val('0'),N1,[_|N2]),
atom_chars(X,['1'|N2]).
:-maplist(figure,[1234,1,0],X),writeln(X).
% 実行結果
% [ (4, 1000), (1, 1), (1, 1)]
|
そこそこ丁寧に
1 2 3 4 | function figure(x){
var len=Math.abs(parseInt(x,10)).toString().length;
return [len,Math.pow(10,len-1)];
}
|
ex) > gawk -fketa.awk 16 2 10 >gawk -fketa.awk 00065536 5 10000 数字の先頭に0がついていない前提なら4行目は不要です。
1 2 3 4 5 6 7 8 9 | BEGIN {
value = ARGV[1]
value = gensub(/^0*([0-9]+)$/, "\\1", "", value)
keta = length(value)
max = "1"
for(i = 0; i < keta - 1; i++) { max = max "0" }
print keta, max
}
|
1 2 3 4 | def solve(n:int) = {
val w = n.toString.length
(w, Math.pow(10, w-1).toInt)
}
|
accumulator 変数2つも要らないのでは?と思われるかもしれませんが OCaml で 10 ** len をやろうと思うとかっこ悪いことになるので…
1 2 3 4 5 6 | let num_digits n =
let rec num_digits' len place = function
| 0 -> (len, place)
| n -> num_digits' (succ len) (place * 10) (n / 10)
in
num_digits' 1 1 (n / 10)
|
とりあえず。
1 | f = lambda i: (len(str(i)), 10 ** (len(str(i)) - 1))
|
1 2 3 4 5 6 | function keta(num) {
for(var n = 0;num >= 1;n++) {
num /= 10;
}
return [n, Math.pow(10, n-1)]
}
|
小数点以下の桁数をどう表現すればいいのか迷いましたが、マイナス方向にそのまま延長しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import java.lang.StrictMath;
public class Sample {
public static void keta(double num) {
int keta = 0;
if (num != 0) {
keta = (int)StrictMath.log10(StrictMath.abs(num));
}
System.out.printf("%d, %g%n", keta + 1, StrictMath.pow(10.0, keta));
}
public static void main(String[] args) {
keta(Double.parseDouble(args[0]));
}
}
|
Squeak Smalltalk で。
1 2 3 4 5 | | n numOfDigits |
n := 2469.
^{numOfDigits := n printString size. 10 raisedTo: numOfDigits - 1}
"=> #(4 1000) "
|
整数だけですが、桁数と位を返せるクラスをつくってみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public class DigitMain {
public static void main(String[] args) {
Digit digit = new Digit(2469);
System.out.println(digit.getNumber() +":" + digit.getUnit());
}
}
public class Digit {
private static int value;
public Digit(int value){
this.value = value;
}
public int getNumber(){
return String.valueOf(value).length();
}
public int getUnit(){
return getNumber() == 1 ? 1 : (int)(Math.pow(10, getNumber()-1));
}
}
|
変数切りすぎかなぁ
1 2 3 4 5 6 | def keta_kurai(num)
keta = num.abs.truncate.to_s.length
kurai = "1"
kurai += "0" * (keta-1) if keta > 1
return keta, kurai
end
|
なんでかloginできないので匿名アカウントで(n某)
1 2 3 | import System.Environment
starling f g x = f x (g x)
main = print . starling (,) ((10^) . subtract 1) . length . head =<< getArgs
|
DrSchemeにて。 > (digits-and-msd 1) (1 . 1) > (digits-and-msd 600) (3 . 100)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | (define (digits-and-msd number)
(cons (digits number) (msd number)))
(define (msd number)
(power 10 (- (digits number) 1)))
(define (digits number)
(cond ((< number 10) 1)
(else (+ 1 (digits (/ number 10))))))
(define (power base exp)
(cond ((= exp 0) 1)
((= exp 1) base)
(else (* base (power base (- exp 1))))))
|
0とか負数のときはどうすればいいんだろう。適当に処理しておいたけど。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
def digits(n):
"""
returns count of digits and order of most siginificant digit.
>>> digits(2469)
(4, 1000)
>>> digits(600)
(3, 100)
>>> digits(1)
(1, 1)
>>> digits(0)
(1, 1)
>>> digits(-100)
(3, 100)
"""
if n < 0:
n = -n
s = str(n)
return (len(s), 10 ** (len(s) - 1))
def _test():
import doctest
doctest.testmod()
if __name__ == '__main__':
_test()
|
整数限定にしておきました。
1 2 3 4 5 6 7 | Public Sub foo(ByVal number As Integer)
Dim length As Integer = number.ToString.Replace("-", "").Length
Console.WriteLine(length)
Console.WriteLine(10 ^ (length - 1))
End Sub
|
初めて投稿します。
1 2 3 4 | BEGIN {
keta = length(0 + ARGV[1])
print keta, 10**(keta - 1)
}
|
awkで書いたやつと同じやり方ですが gosh> (keta+kurai 12345678) 8 10000000
1 2 3 | (define (keta+kurai n)
(let1 keta (string-length (number->string n))
(values keta (expt 10 (- keta 1)))))
|
VisualWorks で。
作った後 sumim さんのをみて、そうだ、文字列にして文字数数えればいいんじゃん... と 自分の頭の固さにガッカリです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | | getDigitsAndPlace |
getDigitsAndPlace :=
[ :var |
| func |
func := [ :x :d |
(10 ** d) <= x
ifTrue: [func value: x value: d + 1]
ifFalse: [ Array with: d with: 10 ** (d-1)]].
func value: var value: 0].
Transcript cr; show: (getDigitsAndPlace value: 2649) printString;
cr; show: (getDigitsAndPlace value: 1) printString;
cr; show: (getDigitsAndPlace value: 600) printString
"== 結果 ==
#(4 1000)
#(1 1)
#(3 100)
"
|
あー、、いきなりヘッポコ、自己レスです。 x はレキシカル変数にでいいですね。自分のヘッポコぶりに絶望した!
1 2 3 4 5 6 7 8 9 | | getDigitsAndPlace |
getDigitsAndPlace :=
[ :x |
| func |
func := [ :d |
(10 ** d) <= x
ifTrue: [func value: d + 1]
ifFalse: [ Array with: d with: 10 ** (d-1)]].
func value: 0].
|
常用対数でやってみました。
使用例:
>> [d,m] = doukaku40(321321)
d =
6
m =
100000
1 2 3 | function [d,m] = doukaku40(n)
d = floor(log10(n)) + 1;
m = 10^(d-1);
|
でも、これだとゼロとかマイナス値のときに破綻しますね。要・再検討。
log使うのは、誤差が入るので、ループでカウントすべきですが、、、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | using System;
class Program
{
static void Main()
{
ShowDigit(2469);
ShowDigit(600);
ShowDigit(1);
}
static void ShowDigit(int k)
{
int n = (int)Math.Log10(k);
Console.WriteLine("{0} {1}", n + 1, Math.Pow(10, n));
}
}
|
例えば1.23の最大桁の位を1とするのか1.00とするのか、、 多分1だと思うのですが、とりあえず両方ともできるようにしてみました。 あと、powを使うのが一番楽ですが、php(?)らしく数値を文字列操作する妙な方法でやってみました。 //1.23 の入力で最大桁数を 1と表示するなら 1-> 1 1 600-> 3 100 9999-> 4 1000 0-> 1 1 -1-> 1 1 -600-> 3 100 -9999-> 4 1000 1.23-> 4 1 -9.99-> 4 1 abc-> error //1.23 の入力で最大桁数を 1.00と表示するなら 1-> 1 1 600-> 3 100 9999-> 4 1000 0-> 1 1 -1-> 1 1 -600-> 3 100 -9999-> 4 1000 1.23-> 4 1.00 -9.99-> 4 1.00 abc-> error
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | <?php
function check($input)
{
//入力が数値以外ならエラー
if(!is_numeric($input))
{
return array("error");
}
//0より小さい(マイナスだったら)+にする
if($input<0)
{
$input=$input*-1;
}
//1.23 の入力で最大桁数を 1.00と表示するなら
// //全ての数値を0にする
// $max_kurai=ereg_replace("[0-9]","0",$input);
// //先頭文字を切り捨てた文字列の先頭に'1'をつなげる
// $max_kurai="1".substr($max_kurai,1,10000000000000);
//1.23 の入力で最大桁数を 1と表示するなら
//全ての桁を9にする
$max_kurai=ereg_replace("[0-9]","9",(int)$input);
//1を足して10で割る 9999 -> 10000 -> 1000
$max_kurai=($max_kurai+1)/10;
//1.23 の入力で最大桁数を 1と表示するなら powを使う
// $max_kurai=pow(10,strlen((int)$input)-1);
return array(strlen($input),$max_kurai);
}
echo "<pre>";
$target=1; $ret=check($target); echo $target."->\t".$ret[0]." ".$ret[1]."\n";
$target=600; $ret=check($target); echo $target."->\t".$ret[0]." ".$ret[1]."\n";
$target=9999; $ret=check($target); echo $target."->\t".$ret[0]." ".$ret[1]."\n";
$target=0; $ret=check($target); echo $target."->\t".$ret[0]." ".$ret[1]."\n";
$target=-1; $ret=check($target); echo $target."->\t".$ret[0]." ".$ret[1]."\n";
$target=-600; $ret=check($target); echo $target."->\t".$ret[0]." ".$ret[1]."\n";
$target=-9999; $ret=check($target); echo $target."->\t".$ret[0]." ".$ret[1]."\n";
$target=9.99; $ret=check($target); echo $target."->\t".$ret[0]." ".$ret[1]."\n";
$target=-9.99; $ret=check($target); echo $target."->\t".$ret[0]." ".$ret[1]."\n";
$target="abc"; $ret=check($target); echo $target."->\t".$ret[0]." ".$ret[1]."\n";
?>
|
しまった。この手がありました。 > (digit-number 316) (3 . 100) > (digit-number 1) (1 . 1)
1 2 3 4 | (define (digit-number number)
(define (digits n) (string-length (number->string n)))
(let ((d (digits number)))
(cons d (expt 10 (- d 1)))))
|
JS版みてアッと思い、abs追加して晒しです。小数点以下はバッサリいってます。
1 2 3 4 | function ketasu(num:Number):Array{
var keta:Number = Math.abs(Math.floor(num)).toString().length;
return(new Array(keta,Math.pow(10,keta-1)));
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class GetKeta {
/** 桁数取得. */
public static int getKeta(int value) {
return String.valueOf(value).length();
}
/** 位. */
public static int getUnit(int value) {
return (int) Math.pow(10d, (double) getKeta(value) - 1);
}
}
|
>og使うのは、誤差が入るので、ループでカウントすべき なるほど。 log10の誤差で答えが間違いになる例を調べてみました。 >>> x = 999999999999999 >>> log10(x) + 1 16.0 >>> len(str(x)) 15
double では有効桁数が足りない場合があるという(他言語での)指摘を受けて BigDecimal を使ってみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import java.math.BigDecimal;
import java.math.MathContext;
public class Sample2 {
public static void keta(BigDecimal num) {
int keta = num.precision() - num.scale();
MathContext ctx = MathContext.DECIMAL32;
System.out.printf("%d, %g%n", keta, BigDecimal.TEN.pow(keta - 1, ctx));
}
public static void main(String[] args) {
keta(new BigDecimal(args[0]));
}
}
|
うーん、素晴らしいコードだとは口が裂けたら言えないけど、マイナス評価喰らうほどひどいかなぁ… #ifじゃなくてcond使ってる辺りはヒドイが(ぉ ##pluspとminuspの振り分けをabsで吸収するまでのアレコレで残っちゃったんだよね。 評価そのものより、評価理由がキニナル(´・ω・`)
あえて数字を文字列にしない方向で
1 | keta x = snd $ head $ filter (\(y,z)-> y > x) $ zip (iterate (*10) 10) $ zip [1..] $ iterate (*10) 1
|
カリー化でちょっとだけ短く
1 | keta x = snd $ head $ filter ((>x).fst) $ zip (iterate (*10) 10) $ zip [1..] $ iterate (*10) 1
|





susu
#3396()
Rating0/0=0.00
このお題はsusuさんの投稿です。ご投稿ありがとうございます。
[ reply ]