C言語
整数値を入力すると、*とスペースを用いたひし形を出力するプログラムを教えていただきたいです。
整数の値はひし形の中央の*の数です。
例:
整数を入力せよ:3
・・・*・・・
・・*〇*・・
・*〇*〇*・
・・*〇*・・
・・・*・・・
「・」「〇」はどちらも空白
よろしくお願い致します。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
プログラムそのものではなく,方法のアイデアの話となりますが…
f(x,y) = cos(x) * cos(y)
という式を考えました.プロットしてみると下図のような形です.
山と谷が交互に繰り返すような形をしています.
床(?)に表示されているのは等高線です.
この交互具合が,やりたいことに似ていると思います.
こいつに適当に2次元正規分布g(x,y)を窓関数として用いてf(x,y)*g(x,y)
としてやれば,
以下のように関数値が上下に振れる範囲を制限でき,雰囲気が本件の問題の内容にかなり近づくと思います.
なので,この関数値に対して適切な閾値による二値化を行った結果を,スペースと'*'とで表示すれば良いのではないでしょうか.
(窓関数の広さとか,関数の位相あたりを入力された値に基づいて変えてやる必要はあると思います)
とりあえず愚直に実装するとこんなですかね.
コメントに書いたように,窓関数g(x,y)はifで置き換わっています.
(別の回答と同様に,数値入力は{面倒/本質ではない}のでdefineで済ませてあります)
C++
1#define N_THE_INPUT (3) 2 3const double PI = acos(-1.0); //π 4 5//f(x,y), 位相調整込み 6double F( double x, double y ) 7{ return ( N_THE_INPUT&0x01 ? cos(x)*cos(y) : -cos(x)*cos(y) ); } 8 9// 10int main(int argc, char *argv[]) 11{ 12 const double Thresh = 0.5; //関数f(x,y)に対する閾値 13 const int RANGE = ( N_THE_INPUT*2 - 1 ); 14 const int RANGE_CENTER = RANGE/2; 15 16 for( int row=0; row<RANGE; ++row ) 17 { 18 printf( "[ " ); 19 for( int col=0; col<RANGE; ++col ) 20 { 21 char out = ' '; 22 const int c = col - RANGE_CENTER; 23 const int r = row - RANGE_CENTER; 24 if( abs(c)+abs(r) < N_THE_INPUT ) //※市街地距離による矩形窓 25 { 26 if( F( PI*c, PI*r ) > Thresh ){ out = '*'; } 27 } 28 putchar( out ); 29 } 30 printf( " ]\n" ); 31 } 32 33 return 0; 34}
投稿2020/11/17 02:39
編集2020/11/18 01:37総合スコア11996
0
いろいろな書き方があります。模範的な解答ではありません。
C
1#include <stdio.h> 2 3int main(void) 4{ 5 for (int s = 0, i = 1, j = 1, n, k = (scanf("%d", &n), n-1); i; ) 6 s==0 ? printf(" " ), !k-- && (k = i, s = 1) : 7 s==1 ? printf("* "), !--k && (k = n-i, s = 2) : 8 !k-- ? printf("\n"), i==n && (j = -1), s = 0, i += j, k = n-i : printf(" "); 9}
追記
fanaさんのコードを参考にしたら、こんなのが書けました。
C
1#include <stdio.h> // scanf, putchar 2#include <stdlib.h> // abs 3 4int main(void) 5{ 6 for (int n, i = (scanf("%d", &n), -n); ++i < n; putchar('\n')) 7 for (int j = -n; j <= n; j++) 8 putchar(" *"[(i+j ^ n) & 1 && abs(i)+abs(j) < n]); 9}
追記2
上記のコードは n が偶数の場合正しくなかったので修正しました。
追記3
fanaさんのライフゲーム風のコードをこんな風に書いてみました。
C
1#include <stdio.h> // scanf, printf 2#include <stdlib.h> // malloc. free 3#include <string.h> // memset 4 5#define transform(k, op) \ 6 for (int i = k; i < n; i++) { \ 7 printf("%.*s\n", w, a); \ 8 for (int j = 0; ++j < w-1; ) b[j] = " *"[a[j-1]=='*' op a[j+1]=='*']; \ 9 t = a, a = b, b = t; \ 10 } 11 12int main(void) { 13 int n, w = (scanf("%d", &n), n*2+1); 14 char *s = malloc(w*2), *a = memset(s, ' ', w*2), *b = (a[n] = '*', s+w), *t; 15 transform(1, |) transform(0, &) free(s); 16}
for文の (;;) を除いて、「;」が 1行に 1つという制約で短縮しています。
投稿2020/11/18 10:53
編集2020/11/20 04:58総合スコア8224
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/11/20 04:52
2020/11/20 05:08 編集
0
行の内容を簡単なルールに従って変換することで次の行の内容を作れるんじゃないか?(ライフゲームみたいに)
…とか思ったのですが,コードも無意味に長いしルールも1つに纏まらないしでイマイチ感.
提示コードでは,
整数値を入力
の部分はめんどくさい(し,話の本質でもない)のでdefineで済ませてます.
C++
1#define N_THE_INPUT (3) 2#define LEN (N_THE_INPUT*2+1) 3 4int Transform( const char *pSrc, char *pDst, int length, int Or ) 5{ 6 int i; 7 int ret = 0; 8 for( i=1; i<length-1; ++i ) 9 { 10 const unsigned char s1 = ( *(pSrc+i-1) == '*' ); 11 const unsigned char s2 = ( *(pSrc+i+1) == '*' ); 12 *(pDst+i) = ' '; 13 if( Or ? (s1 || s2) : (s1 && s2) ) 14 { 15 *(pDst+i) = '*'; 16 ++ret; 17 } 18 } 19 return ret; 20} 21 22int OrTransform( const char *pSrc, char *pDst, int length ) 23{ return Transform( pSrc, pDst, length, 1 ); } 24 25int AndTransform( const char *pSrc, char *pDst, int length ) 26{ return Transform( pSrc, pDst, length, 0 ); } 27 28void Init( char *pDst, int length ) 29{ 30 int i; 31 for( i=0; i<length; ++i ){ *(pDst+i)=' '; } 32} 33 34// 35int main(int argc, char *argv[]) 36{ 37 char Buff1[LEN+1] = { '\0' }; 38 char Buff2[LEN+1] = { '\0' }; 39 char *pS = Buff1; 40 char *pD = Buff2; 41 char *pT; 42 int n = 1; 43 44 Init( pS, LEN ); 45 Init( pD, LEN ); 46 47 { 48 *(pD+LEN/2) = '*'; 49 printf( "[%s]\n", pD ); 50 } 51 52 while( n < N_THE_INPUT ) 53 { 54 pT = pS; 55 pS = pD; 56 pD = pT; 57 n = OrTransform( pS, pD, LEN ); 58 printf( "[%s]\n", pD ); 59 } 60 61 while( n>1 ) 62 { 63 pT = pS; 64 pS = pD; 65 pD = pT; 66 n = AndTransform( pS, pD, LEN ); 67 printf( "[%s]\n", pD ); 68 } 69 70 return 0; 71}
投稿2020/11/17 05:08
総合スコア11996
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/11/17 02:50 編集
2020/11/17 07:24
2020/11/17 08:44 編集